mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
manual merge
This commit is contained in:
@ -3107,7 +3107,6 @@ slave_begin:
|
|||||||
sql_print_error("Failed during slave thread initialization");
|
sql_print_error("Failed during slave thread initialization");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
thd->init_for_queries();
|
|
||||||
rli->sql_thd= thd;
|
rli->sql_thd= thd;
|
||||||
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
|
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
|
||||||
pthread_mutex_lock(&LOCK_thread_count);
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
|
105
sql/sql_class.cc
105
sql/sql_class.cc
@ -86,28 +86,28 @@ extern "C" void free_user_var(user_var_entry *entry)
|
|||||||
** Thread specific functions
|
** Thread specific functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
THD::THD():user_time(0), is_fatal_error(0),
|
THD::THD():user_time(0),
|
||||||
|
is_fatal_error(0),
|
||||||
last_insert_id_used(0),
|
last_insert_id_used(0),
|
||||||
insert_id_used(0), rand_used(0), in_lock_tables(0),
|
insert_id_used(0), rand_used(0), in_lock_tables(0),
|
||||||
global_read_lock(0), bootstrap(0), spcont(NULL)
|
global_read_lock(0), bootstrap(0), spcont(NULL)
|
||||||
{
|
{
|
||||||
lex= &main_lex;
|
host= user= priv_user= db= ip= 0;
|
||||||
host=user=priv_user=db=query=ip=0;
|
|
||||||
host_or_ip= "connecting host";
|
host_or_ip= "connecting host";
|
||||||
locked=some_tables_deleted=no_errors=password= 0;
|
locked=some_tables_deleted=no_errors=password= 0;
|
||||||
query_start_used= 0;
|
query_start_used= 0;
|
||||||
count_cuted_fields= CHECK_FIELD_IGNORE;
|
count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||||
killed= NOT_KILLED;
|
killed= NOT_KILLED;
|
||||||
db_length=query_length=col_access=0;
|
db_length= col_access=0;
|
||||||
query_error= tmp_table_used= 0;
|
query_error= tmp_table_used= 0;
|
||||||
next_insert_id=last_insert_id=0;
|
next_insert_id=last_insert_id=0;
|
||||||
open_tables= temporary_tables= handler_tables= derived_tables= 0;
|
open_tables= temporary_tables= handler_tables= derived_tables= 0;
|
||||||
tmp_table=0;
|
tmp_table=0;
|
||||||
lock=locked_tables=0;
|
lock=locked_tables=0;
|
||||||
used_tables=0;
|
used_tables=0;
|
||||||
cuted_fields= sent_row_count= current_stmt_id= 0L;
|
cuted_fields= sent_row_count= 0L;
|
||||||
|
statement_id_counter= 0UL;
|
||||||
// Must be reset to handle error with THD's created for init of mysqld
|
// Must be reset to handle error with THD's created for init of mysqld
|
||||||
lex->current_select= 0;
|
|
||||||
start_time=(time_t) 0;
|
start_time=(time_t) 0;
|
||||||
current_linfo = 0;
|
current_linfo = 0;
|
||||||
slave_thread = 0;
|
slave_thread = 0;
|
||||||
@ -141,7 +141,6 @@ THD::THD():user_time(0), is_fatal_error(0),
|
|||||||
server_id = ::server_id;
|
server_id = ::server_id;
|
||||||
slave_net = 0;
|
slave_net = 0;
|
||||||
command=COM_CONNECT;
|
command=COM_CONNECT;
|
||||||
set_query_id=1;
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
db_access=NO_ACCESS;
|
db_access=NO_ACCESS;
|
||||||
#endif
|
#endif
|
||||||
@ -149,6 +148,9 @@ THD::THD():user_time(0), is_fatal_error(0),
|
|||||||
*scramble= '\0';
|
*scramble= '\0';
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
init_sql_alloc(&mem_root, // must be after init()
|
||||||
|
variables.query_alloc_block_size,
|
||||||
|
variables.query_prealloc_size);
|
||||||
/* Initialize sub structures */
|
/* Initialize sub structures */
|
||||||
bzero((char*) &mem_root,sizeof(mem_root));
|
bzero((char*) &mem_root,sizeof(mem_root));
|
||||||
init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
|
init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
|
||||||
@ -192,7 +194,9 @@ THD::THD():user_time(0), is_fatal_error(0),
|
|||||||
transaction.trans_log.end_of_file= max_binlog_cache_size;
|
transaction.trans_log.end_of_file= max_binlog_cache_size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
init_sql_alloc(&transaction.mem_root,
|
||||||
|
variables.trans_alloc_block_size,
|
||||||
|
variables.trans_prealloc_size);
|
||||||
/*
|
/*
|
||||||
We need good random number initialization for new thread
|
We need good random number initialization for new thread
|
||||||
Just coping global one will not work
|
Just coping global one will not work
|
||||||
@ -235,22 +239,6 @@ void THD::init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Init THD for query processing
|
|
||||||
|
|
||||||
This has to be called once before we call mysql_parse()
|
|
||||||
*/
|
|
||||||
|
|
||||||
void THD::init_for_queries()
|
|
||||||
{
|
|
||||||
init_sql_alloc(&mem_root, variables.query_alloc_block_size,
|
|
||||||
variables.query_prealloc_size);
|
|
||||||
init_sql_alloc(&transaction.mem_root,
|
|
||||||
variables.trans_alloc_block_size,
|
|
||||||
variables.trans_prealloc_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do what's needed when one invokes change user
|
Do what's needed when one invokes change user
|
||||||
|
|
||||||
@ -351,7 +339,6 @@ THD::~THD()
|
|||||||
safeFree(user);
|
safeFree(user);
|
||||||
safeFree(db);
|
safeFree(db);
|
||||||
safeFree(ip);
|
safeFree(ip);
|
||||||
free_root(&mem_root,MYF(0));
|
|
||||||
free_root(&warn_root,MYF(0));
|
free_root(&warn_root,MYF(0));
|
||||||
free_root(&transaction.mem_root,MYF(0));
|
free_root(&transaction.mem_root,MYF(0));
|
||||||
mysys_var=0; // Safety (shouldn't be needed)
|
mysys_var=0; // Safety (shouldn't be needed)
|
||||||
@ -1280,3 +1267,71 @@ void TMP_TABLE_PARAM::init()
|
|||||||
group_parts= group_length= group_null_parts= 0;
|
group_parts= group_length= group_null_parts= 0;
|
||||||
quick_group= 1;
|
quick_group= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Statement functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
Statement::Statement(THD *thd)
|
||||||
|
:id(++thd->statement_id_counter),
|
||||||
|
query_id(0), /* initialized later */
|
||||||
|
set_query_id(1),
|
||||||
|
allow_sum_func(0), /* initialized later */
|
||||||
|
command(COM_SLEEP), /* reset in THD counstructor and mysql_parse */
|
||||||
|
lex(&main_lex),
|
||||||
|
query(0),
|
||||||
|
query_length(0),
|
||||||
|
free_list(0) /* reset in THD constructor */
|
||||||
|
{
|
||||||
|
init_sql_alloc(&mem_root,
|
||||||
|
thd->variables.query_alloc_block_size,
|
||||||
|
thd->variables.query_prealloc_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This constructor is called when statement is a subobject of THD:
|
||||||
|
Some variables are initialized in THD::init due to locking problems
|
||||||
|
This statement object will be used to hold state of currently active
|
||||||
|
statement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Statement::Statement()
|
||||||
|
:id(0),
|
||||||
|
query_id(0),
|
||||||
|
set_query_id(1),
|
||||||
|
allow_sum_func(0),
|
||||||
|
command(COM_SLEEP),
|
||||||
|
lex(&main_lex),
|
||||||
|
query(0),
|
||||||
|
query_length(0),
|
||||||
|
free_list(0)
|
||||||
|
{
|
||||||
|
bzero((char *) &mem_root, sizeof(mem_root));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Statement::~Statement()
|
||||||
|
{
|
||||||
|
free_root(&mem_root, MYF(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
C_MODE_START
|
||||||
|
|
||||||
|
static byte *
|
||||||
|
get_statement_id_as_hash_key(const byte *record, uint *key_length,
|
||||||
|
my_bool not_used __attribute__((unused)))
|
||||||
|
{
|
||||||
|
const Statement *statement= (const Statement *) record;
|
||||||
|
*key_length= sizeof(statement->id);
|
||||||
|
return (byte *) &((const Statement *) statement)->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_MODE_END
|
||||||
|
|
||||||
|
Statement_map::Statement_map()
|
||||||
|
{
|
||||||
|
enum { START_HASH_SIZE = 16 };
|
||||||
|
hash_init(&st_hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||||
|
get_statement_id_as_hash_key, (hash_free_key) 0, MYF(0));
|
||||||
|
}
|
||||||
|
134
sql/sql_class.h
134
sql/sql_class.h
@ -431,12 +431,126 @@ struct system_variables
|
|||||||
};
|
};
|
||||||
|
|
||||||
void free_tmp_table(THD *thd, TABLE *entry);
|
void free_tmp_table(THD *thd, TABLE *entry);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* FIXME: must be private */
|
||||||
|
LEX main_lex;
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
Uniquely identifies each statement object in scope of thread.
|
||||||
|
Can't be const at the moment because of substitute() method
|
||||||
|
*/
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Statement();
|
||||||
|
public:
|
||||||
|
Statement(THD *thd);
|
||||||
|
virtual ~Statement();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used to seek all existing statements in the connection
|
||||||
|
Not responsible for statements memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Statement_map
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Statement_map();
|
||||||
|
|
||||||
|
int insert(Statement *statement)
|
||||||
|
{
|
||||||
|
return my_hash_insert(&st_hash, (byte *) statement);
|
||||||
|
}
|
||||||
|
Statement *seek(ulonglong id)
|
||||||
|
{
|
||||||
|
return (Statement *) hash_search(&st_hash, (byte *) &id, sizeof(id));
|
||||||
|
}
|
||||||
|
void erase(Statement *statement)
|
||||||
|
{
|
||||||
|
hash_delete(&st_hash, (byte *) statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Statement_map() { hash_free(&st_hash); }
|
||||||
|
private:
|
||||||
|
HASH st_hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For each client connection we create a separate thread with THD serving as
|
For each client connection we create a separate thread with THD serving as
|
||||||
a thread/connection descriptor
|
a thread/connection descriptor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class THD :public ilink
|
class THD :public ilink,
|
||||||
|
public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef EMBEDDED_LIBRARY
|
#ifdef EMBEDDED_LIBRARY
|
||||||
@ -449,9 +563,6 @@ public:
|
|||||||
ulong extra_length;
|
ulong extra_length;
|
||||||
#endif
|
#endif
|
||||||
NET net; // client connection descriptor
|
NET net; // client connection descriptor
|
||||||
LEX main_lex;
|
|
||||||
LEX *lex; // parse tree descriptor
|
|
||||||
MEM_ROOT mem_root; // 1 command-life memory pool
|
|
||||||
MEM_ROOT warn_root; // For warnings and errors
|
MEM_ROOT warn_root; // For warnings and errors
|
||||||
Protocol *protocol; // Current protocol
|
Protocol *protocol; // Current protocol
|
||||||
Protocol_simple protocol_simple; // Normal protocol
|
Protocol_simple protocol_simple; // Normal protocol
|
||||||
@ -464,7 +575,6 @@ public:
|
|||||||
struct system_variables variables; // Changeable local variables
|
struct system_variables variables; // Changeable local variables
|
||||||
pthread_mutex_t LOCK_delete; // Locked before thd is deleted
|
pthread_mutex_t LOCK_delete; // Locked before thd is deleted
|
||||||
|
|
||||||
char *query; // Points to the current query,
|
|
||||||
/*
|
/*
|
||||||
A pointer to the stack frame of handle_one_connection(),
|
A pointer to the stack frame of handle_one_connection(),
|
||||||
which is called first in the thread for handling a client
|
which is called first in the thread for handling a client
|
||||||
@ -513,7 +623,6 @@ public:
|
|||||||
uint dbug_sentry; // watch out for memory corruption
|
uint dbug_sentry; // watch out for memory corruption
|
||||||
#endif
|
#endif
|
||||||
struct st_my_thread_var *mysys_var;
|
struct st_my_thread_var *mysys_var;
|
||||||
enum enum_server_command command;
|
|
||||||
uint32 server_id;
|
uint32 server_id;
|
||||||
uint32 file_id; // for LOAD DATA INFILE
|
uint32 file_id; // for LOAD DATA INFILE
|
||||||
/*
|
/*
|
||||||
@ -546,7 +655,6 @@ public:
|
|||||||
free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
|
free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
|
||||||
}
|
}
|
||||||
} transaction;
|
} transaction;
|
||||||
Item *free_list;
|
|
||||||
Field *dupp_field;
|
Field *dupp_field;
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
sigset_t signals,block_signals;
|
sigset_t signals,block_signals;
|
||||||
@ -580,15 +688,16 @@ public:
|
|||||||
List <MYSQL_ERROR> warn_list;
|
List <MYSQL_ERROR> warn_list;
|
||||||
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
||||||
uint total_warn_count;
|
uint total_warn_count;
|
||||||
ulong query_id, warn_id, version, options, thread_id, col_access;
|
ulong warn_id, version, options, thread_id, col_access;
|
||||||
ulong current_stmt_id;
|
|
||||||
|
/* Statement id is thread-wide. This counter is used to generate ids */
|
||||||
|
ulong statement_id_counter;
|
||||||
ulong rand_saved_seed1, rand_saved_seed2;
|
ulong rand_saved_seed1, rand_saved_seed2;
|
||||||
ulong row_count; // Row counter, mainly for errors and warnings
|
ulong row_count; // Row counter, mainly for errors and warnings
|
||||||
long dbug_thread_id;
|
long dbug_thread_id;
|
||||||
pthread_t real_id;
|
pthread_t real_id;
|
||||||
uint current_tablenr,tmp_table;
|
uint current_tablenr,tmp_table;
|
||||||
uint server_status,open_options;
|
uint server_status,open_options;
|
||||||
uint32 query_length;
|
|
||||||
uint32 db_length;
|
uint32 db_length;
|
||||||
uint select_number; //number of select (used for EXPLAIN)
|
uint select_number; //number of select (used for EXPLAIN)
|
||||||
/* variables.transaction_isolation is reset to this after each commit */
|
/* variables.transaction_isolation is reset to this after each commit */
|
||||||
@ -601,9 +710,9 @@ public:
|
|||||||
char scramble[SCRAMBLE_LENGTH+1];
|
char scramble[SCRAMBLE_LENGTH+1];
|
||||||
|
|
||||||
bool slave_thread;
|
bool slave_thread;
|
||||||
bool set_query_id,locked,some_tables_deleted;
|
bool locked, some_tables_deleted;
|
||||||
bool last_cuted_field;
|
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 query_start_used,last_insert_id_used,insert_id_used,rand_used;
|
||||||
bool system_thread,in_lock_tables,global_read_lock;
|
bool system_thread,in_lock_tables,global_read_lock;
|
||||||
bool query_error, bootstrap, cleanup_done;
|
bool query_error, bootstrap, cleanup_done;
|
||||||
@ -646,7 +755,6 @@ public:
|
|||||||
|
|
||||||
void init(void);
|
void init(void);
|
||||||
void change_user(void);
|
void change_user(void);
|
||||||
void init_for_queries();
|
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
bool store_globals();
|
bool store_globals();
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
|
@ -948,7 +948,6 @@ pthread_handler_decl(handle_one_connection,arg)
|
|||||||
thd->command=COM_SLEEP;
|
thd->command=COM_SLEEP;
|
||||||
thd->version=refresh_version;
|
thd->version=refresh_version;
|
||||||
thd->set_time();
|
thd->set_time();
|
||||||
thd->init_for_queries();
|
|
||||||
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
|
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
|
||||||
{
|
{
|
||||||
if (do_command(thd))
|
if (do_command(thd))
|
||||||
@ -1028,7 +1027,6 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
|
|||||||
thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
|
thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
|
||||||
|
|
||||||
buff= (char*) thd->net.buff;
|
buff= (char*) thd->net.buff;
|
||||||
thd->init_for_queries();
|
|
||||||
while (fgets(buff, thd->net.max_packet, file))
|
while (fgets(buff, thd->net.max_packet, file))
|
||||||
{
|
{
|
||||||
uint length=(uint) strlen(buff);
|
uint length=(uint) strlen(buff);
|
||||||
|
@ -901,7 +901,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
|
|||||||
|
|
||||||
bzero((char*) &stmt, sizeof(stmt));
|
bzero((char*) &stmt, sizeof(stmt));
|
||||||
|
|
||||||
stmt.stmt_id= ++thd->current_stmt_id;
|
stmt.stmt_id= ++thd->statement_id_counter;
|
||||||
init_sql_alloc(&stmt.mem_root,
|
init_sql_alloc(&stmt.mem_root,
|
||||||
thd->variables.query_alloc_block_size,
|
thd->variables.query_alloc_block_size,
|
||||||
thd->variables.query_prealloc_size);
|
thd->variables.query_prealloc_size);
|
||||||
|
Reference in New Issue
Block a user