mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Desperate attempt to push part of prepared statements cleanup which was
reviewed in Saint-Petersbourg (including post-review fixes).
This commit is contained in:
parent
0a27eef814
commit
8cc8b0ea5c
11 changed files with 437 additions and 395 deletions
|
@ -714,6 +714,7 @@ extern void my_free_lock(byte *ptr,myf flags);
|
||||||
#define my_free_lock(A,B) my_free((A),(B))
|
#define my_free_lock(A,B) my_free((A),(B))
|
||||||
#endif
|
#endif
|
||||||
#define alloc_root_inited(A) ((A)->min_malloc != 0)
|
#define alloc_root_inited(A) ((A)->min_malloc != 0)
|
||||||
|
#define clear_alloc_root(A) bzero((void *) (A), sizeof(MEM_ROOT))
|
||||||
extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
|
extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
|
||||||
uint pre_alloc_size);
|
uint pre_alloc_size);
|
||||||
extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
|
extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
|
||||||
|
|
|
@ -375,9 +375,9 @@ public:
|
||||||
bool get_time(TIME *tm);
|
bool get_time(TIME *tm);
|
||||||
void reset() {}
|
void reset() {}
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
void (*setup_param_func)(Item_param *param, uchar **pos);
|
void (*set_param_func)(Item_param *param, uchar **pos);
|
||||||
#else
|
#else
|
||||||
void (*setup_param_func)(Item_param *param, uchar **pos, ulong data_len);
|
void (*set_param_func)(Item_param *param, uchar **pos, ulong data_len);
|
||||||
#endif
|
#endif
|
||||||
enum Item_result result_type () const
|
enum Item_result result_type () const
|
||||||
{ return item_result_type; }
|
{ return item_result_type; }
|
||||||
|
|
|
@ -620,14 +620,13 @@ int mysqld_show_column_types(THD *thd);
|
||||||
int mysqld_help (THD *thd, const char *text);
|
int mysqld_help (THD *thd, const char *text);
|
||||||
|
|
||||||
/* sql_prepare.cc */
|
/* sql_prepare.cc */
|
||||||
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length);
|
void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length);
|
||||||
void mysql_stmt_execute(THD *thd, char *packet);
|
void mysql_stmt_execute(THD *thd, char *packet);
|
||||||
void mysql_stmt_free(THD *thd, char *packet);
|
void mysql_stmt_free(THD *thd, char *packet);
|
||||||
void mysql_stmt_reset(THD *thd, char *packet);
|
void mysql_stmt_reset(THD *thd, char *packet);
|
||||||
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
|
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
|
||||||
int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
|
int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
|
||||||
List<Item> &values, ulong counter);
|
List<Item> &values, ulong counter);
|
||||||
void setup_param_functions(Item_param *param, uchar param_type);
|
|
||||||
|
|
||||||
/* sql_error.cc */
|
/* sql_error.cc */
|
||||||
MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
|
MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
|
||||||
|
|
|
@ -178,8 +178,3 @@ char *net_store_data(char *to,const char *from, uint length);
|
||||||
char *net_store_data(char *to,int32 from);
|
char *net_store_data(char *to,int32 from);
|
||||||
char *net_store_data(char *to,longlong from);
|
char *net_store_data(char *to,longlong from);
|
||||||
|
|
||||||
#ifdef EMBEDDED_LIBRARY
|
|
||||||
bool setup_params_data(struct st_prep_stmt *stmt);
|
|
||||||
bool setup_params_data_withlog(struct st_prep_stmt *stmt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
|
@ -145,8 +145,7 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
|
||||||
|
|
||||||
init();
|
init();
|
||||||
/* Initialize sub structures */
|
/* Initialize sub structures */
|
||||||
bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root));
|
clear_alloc_root(&transaction.mem_root);
|
||||||
bzero((char*) &warn_root,sizeof(warn_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);
|
||||||
user_connect=(USER_CONN *)0;
|
user_connect=(USER_CONN *)0;
|
||||||
hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
|
hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
|
||||||
|
@ -331,7 +330,7 @@ THD::~THD()
|
||||||
dbug_sentry = THD_SENTRY_GONE;
|
dbug_sentry = THD_SENTRY_GONE;
|
||||||
#endif
|
#endif
|
||||||
/* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */
|
/* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */
|
||||||
init_alloc_root(&stmt_backup.mem_root, 0, 0);
|
clear_alloc_root(&stmt_backup.mem_root);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,10 +1184,8 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
||||||
|
|
||||||
Statement::Statement(THD *thd)
|
Statement::Statement(THD *thd)
|
||||||
:id(++thd->statement_id_counter),
|
:id(++thd->statement_id_counter),
|
||||||
query_id(thd->query_id),
|
|
||||||
set_query_id(1),
|
set_query_id(1),
|
||||||
allow_sum_func(0),
|
allow_sum_func(0),
|
||||||
command(thd->command),
|
|
||||||
lex(&main_lex),
|
lex(&main_lex),
|
||||||
query(0),
|
query(0),
|
||||||
query_length(0),
|
query_length(0),
|
||||||
|
@ -1207,10 +1204,8 @@ Statement::Statement(THD *thd)
|
||||||
|
|
||||||
Statement::Statement()
|
Statement::Statement()
|
||||||
:id(0),
|
:id(0),
|
||||||
query_id(0), /* initialized later */
|
|
||||||
set_query_id(1),
|
set_query_id(1),
|
||||||
allow_sum_func(0), /* initialized later */
|
allow_sum_func(0), /* initialized later */
|
||||||
command(COM_SLEEP), /* initialized later */
|
|
||||||
lex(&main_lex),
|
lex(&main_lex),
|
||||||
query(0), /* these two are set */
|
query(0), /* these two are set */
|
||||||
query_length(0), /* in alloc_query() */
|
query_length(0), /* in alloc_query() */
|
||||||
|
@ -1229,15 +1224,11 @@ Statement::Type Statement::type() const
|
||||||
void Statement::set_statement(Statement *stmt)
|
void Statement::set_statement(Statement *stmt)
|
||||||
{
|
{
|
||||||
id= stmt->id;
|
id= stmt->id;
|
||||||
query_id= stmt->query_id;
|
|
||||||
set_query_id= stmt->set_query_id;
|
set_query_id= stmt->set_query_id;
|
||||||
allow_sum_func= stmt->allow_sum_func;
|
allow_sum_func= stmt->allow_sum_func;
|
||||||
command= stmt->command;
|
|
||||||
lex= stmt->lex;
|
lex= stmt->lex;
|
||||||
query= stmt->query;
|
query= stmt->query;
|
||||||
query_length= stmt->query_length;
|
query_length= stmt->query_length;
|
||||||
free_list= stmt->free_list;
|
|
||||||
mem_root= stmt->mem_root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -434,15 +434,6 @@ public:
|
||||||
*/
|
*/
|
||||||
ulong id;
|
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
|
- if set_query_id=1, we set field->query_id for all fields. In that case
|
||||||
field list can not contain duplicates.
|
field list can not contain duplicates.
|
||||||
|
@ -461,11 +452,6 @@ public:
|
||||||
See item_sum.cc for details.
|
See item_sum.cc for details.
|
||||||
*/
|
*/
|
||||||
bool allow_sum_func;
|
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
|
LEX *lex; // parse tree descriptor
|
||||||
/*
|
/*
|
||||||
|
@ -676,6 +662,11 @@ 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;
|
||||||
|
/*
|
||||||
|
Type of current query: COM_PREPARE, COM_QUERY, etc. Set from
|
||||||
|
first byte of the packet in do_command()
|
||||||
|
*/
|
||||||
|
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
|
||||||
/*
|
/*
|
||||||
|
@ -751,6 +742,15 @@ 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;
|
||||||
|
/*
|
||||||
|
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;
|
||||||
ulong warn_id, version, options, thread_id, col_access;
|
ulong warn_id, version, options, thread_id, col_access;
|
||||||
|
|
||||||
/* Statement id is thread-wide. This counter is used to generate ids */
|
/* Statement id is thread-wide. This counter is used to generate ids */
|
||||||
|
|
|
@ -552,7 +552,7 @@ typedef struct st_lex
|
||||||
List<Item> *insert_list,field_list,value_list;
|
List<Item> *insert_list,field_list,value_list;
|
||||||
List<List_item> many_values;
|
List<List_item> many_values;
|
||||||
List<set_var_base> var_list;
|
List<set_var_base> var_list;
|
||||||
List<Item> param_list;
|
List<Item_param> param_list;
|
||||||
SQL_LIST proc_list, auxilliary_table_list, save_list;
|
SQL_LIST proc_list, auxilliary_table_list, save_list;
|
||||||
TYPELIB *interval;
|
TYPELIB *interval;
|
||||||
create_field *last_field;
|
create_field *last_field;
|
||||||
|
@ -577,7 +577,6 @@ typedef struct st_lex
|
||||||
uint uint_geom_type;
|
uint uint_geom_type;
|
||||||
uint grant, grant_tot_col, which_columns;
|
uint grant, grant_tot_col, which_columns;
|
||||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||||
uint param_count;
|
|
||||||
uint slave_thd_opt;
|
uint slave_thd_opt;
|
||||||
uint8 describe;
|
uint8 describe;
|
||||||
bool drop_if_exists, drop_temporary, local_file;
|
bool drop_if_exists, drop_temporary, local_file;
|
||||||
|
|
|
@ -1232,10 +1232,34 @@ bool do_command(THD *thd)
|
||||||
command_name[command]));
|
command_name[command]));
|
||||||
}
|
}
|
||||||
net->read_timeout=old_timeout; // restore it
|
net->read_timeout=old_timeout; // restore it
|
||||||
|
/*
|
||||||
|
packet_length contains length of data, as it was stored in packet
|
||||||
|
header. In case of malformed header, packet_length can be zero.
|
||||||
|
If packet_length is not zero, my_net_read ensures that this number
|
||||||
|
of bytes was actually read from network. Additionally my_net_read
|
||||||
|
sets packet[packet_length]= 0 (thus if packet_length == 0,
|
||||||
|
command == packet[0] == COM_SLEEP).
|
||||||
|
In dispatch_command packet[packet_length] points beyond the end of packet.
|
||||||
|
*/
|
||||||
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
||||||
}
|
}
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Perform one connection-level (COM_XXXX) command.
|
||||||
|
SYNOPSIS
|
||||||
|
dispatch_command()
|
||||||
|
thd connection handle
|
||||||
|
command type of command to perform
|
||||||
|
packet data for the command, packet is always null-terminated
|
||||||
|
packet_length length of packet + 1 (to show that data is
|
||||||
|
null-terminated) except for COM_SLEEP, where it
|
||||||
|
can be zero.
|
||||||
|
RETURN VALUE
|
||||||
|
0 ok
|
||||||
|
1 request of thread shutdown, i. e. if command is
|
||||||
|
COM_QUIT/COM_SHUTDOWN
|
||||||
|
*/
|
||||||
|
|
||||||
bool dispatch_command(enum enum_server_command command, THD *thd,
|
bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||||
char* packet, uint packet_length)
|
char* packet, uint packet_length)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4478,11 +4478,17 @@ text_string:
|
||||||
param_marker:
|
param_marker:
|
||||||
'?'
|
'?'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
THD *thd=YYTHD;
|
||||||
if (YYTHD->command == COM_PREPARE)
|
LEX *lex= thd->lex;
|
||||||
|
if (thd->command == COM_PREPARE)
|
||||||
{
|
{
|
||||||
lex->param_list.push_back($$=new Item_param((uint)(lex->tok_start-(uchar *)YYTHD->query)));
|
Item_param *item= new Item_param((uint) (lex->tok_start -
|
||||||
lex->param_count++;
|
(uchar *) thd->query));
|
||||||
|
if (!($$= item) || lex->param_list.push_back(item))
|
||||||
|
{
|
||||||
|
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -8470,8 +8470,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
start_time= time((time_t *)0);
|
start_time= time((time_t *)0);
|
||||||
|
|
||||||
test_subqueries();
|
|
||||||
|
|
||||||
client_query(); /* simple client query test */
|
client_query(); /* simple client query test */
|
||||||
#if NOT_YET_WORKING
|
#if NOT_YET_WORKING
|
||||||
/* Used for internal new development debugging */
|
/* Used for internal new development debugging */
|
||||||
|
|
Loading…
Reference in a new issue