diff options
author | hf@deer.(none) <> | 2003-09-16 16:06:25 +0500 |
---|---|---|
committer | hf@deer.(none) <> | 2003-09-16 16:06:25 +0500 |
commit | bf017a2eb02db66afc70b8b03288f6e30d1907f2 (patch) | |
tree | e38da8c154875ca2ff180275d93d7dfa211f0f14 /libmysqld | |
parent | e63e2229b600926c1792e4e7ca56112dcb1d28bb (diff) | |
download | mariadb-git-bf017a2eb02db66afc70b8b03288f6e30d1907f2.tar.gz |
SCRUM
Prepared statements in embedded server
Several changes in library code with two goals:
to make mysql_prepare_stmt working in embedded server
to get rid of #define mysql_interface_func mysql->methods->interface_func
in user's interface
Diffstat (limited to 'libmysqld')
-rw-r--r-- | libmysqld/embedded_priv.h | 3 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 154 | ||||
-rw-r--r-- | libmysqld/libmysqld.c | 145 |
3 files changed, 114 insertions, 188 deletions
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index dfc06e38ab2..833cc1b1f80 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -26,4 +26,7 @@ C_MODE_START extern void lib_connection_phase(NET *net, int phase); extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); extern void *create_embedded_thd(int client_flag, char *db); +extern MYSQL_METHODS embedded_methods; +void free_old_query(MYSQL *mysql); +extern my_bool server_inited; C_MODE_END diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index c894621be54..1d7f0e4db87 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -50,7 +50,7 @@ static bool check_user(THD *thd, enum_server_command command, char * get_mysql_home(){ return mysql_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;}; -my_bool STDCALL +static my_bool STDCALL emb_advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, const char *arg, ulong arg_length, my_bool skip_check) @@ -94,6 +94,77 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, return result; } +static MYSQL_DATA * STDCALL +emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), + uint fields __attribute__((unused))) +{ + MYSQL_DATA *result= ((THD*)mysql->thd)->data; + if (!result) + return NULL; + *result->prev_ptr= NULL; + ((THD*)mysql->thd)->data= NULL; + return result; +} + +static MYSQL_FIELD * STDCALL emb_list_fields(MYSQL *mysql) +{ + return mysql->fields; +} + +static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) +{ + THD *thd= (THD*)mysql->thd; + stmt->stmt_id= thd->client_stmt_id; + stmt->param_count= thd->client_param_count; + stmt->field_count= mysql->field_count; + + if (stmt->field_count != 0) + { + if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) + mysql->server_status|= SERVER_STATUS_IN_TRANS; + + stmt->fields= mysql->fields; + stmt->mem_root= mysql->field_alloc; + } + return 0; +} + +/************************************************************************** + Get column lengths of the current row + If one uses mysql_use_result, res->lengths contains the length information, + else the lengths are calculated from the offset between pointers. +**************************************************************************/ + +static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) +{ + MYSQL_ROW end; + + for (end=column + field_count; column != end ; column++,to++) + *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0; +} + +static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) +{ + if (mysql->net.last_errno) + return -1; + + if (mysql->field_count) + mysql->status=MYSQL_STATUS_GET_RESULT; + + return 0; +} + +MYSQL_METHODS embedded_methods= +{ + emb_mysql_read_query_result, + emb_advanced_command, + emb_read_rows, + mysql_store_result, + emb_fetch_lengths, + emb_list_fields, + emb_read_prepare_result +}; + C_MODE_END void THD::clear_error() @@ -334,6 +405,8 @@ void *create_embedded_thd(int client_flag, char *db) thd->master_access= ~NO_ACCESS; thd->net.query_cache_query= 0; + thd->data= 0; + return thd; } @@ -343,35 +416,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag) { List_iterator_fast<Item> it(*list); Item *item; - MYSQL_FIELD *field, *client_field; + MYSQL_FIELD *client_field; MYSQL *mysql= thd->mysql; + MEM_ROOT *field_alloc; DBUG_ENTER("send_fields"); field_count= list->elements; - if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ - sizeof(ulong) * (field_count + 1), - MYF(MY_WME | MY_ZEROFILL)))) - goto err; - mysql->result->lengths= (ulong *)(mysql->result + 1); - - mysql->field_count=field_count; - alloc= &mysql->field_alloc; - field= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD) * field_count); - if (!field) + field_alloc= &mysql->field_alloc; + if (!(client_field= thd->mysql->fields= + (MYSQL_FIELD *)alloc_root(field_alloc, + sizeof(MYSQL_FIELD) * field_count))) goto err; - client_field= field; while ((item= it++)) { Send_field server_field; item->make_field(&server_field); - client_field->db= strdup_root(alloc, server_field.db_name); - client_field->table= strdup_root(alloc, server_field.table_name); - client_field->name= strdup_root(alloc, server_field.col_name); - client_field->org_table= strdup_root(alloc, server_field.org_table_name); - client_field->org_name= strdup_root(alloc, server_field.org_col_name); + client_field->db= strdup_root(field_alloc, server_field.db_name); + client_field->table= strdup_root(field_alloc, server_field.table_name); + client_field->name= strdup_root(field_alloc, server_field.col_name); + client_field->org_table= strdup_root(field_alloc, server_field.org_table_name); + client_field->org_name= strdup_root(field_alloc, server_field.org_col_name); client_field->length= server_field.length; client_field->type= server_field.type; client_field->flags= server_field.flags; @@ -392,31 +459,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag) String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res=item->val_str(&tmp))) - client_field->def= strdup_root(alloc, ""); + client_field->def= strdup_root(field_alloc, ""); else - client_field->def= strdup_root(alloc, tmp.ptr()); + client_field->def= strdup_root(field_alloc, tmp.ptr()); } else client_field->def=0; client_field->max_length= 0; ++client_field; } - mysql->result->fields = field; - - if (!(mysql->result->data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), - MYF(MY_WME | MY_ZEROFILL)))) - goto err; - - init_alloc_root(&mysql->result->data->alloc,8192,0); /* Assume rowlength < 8192 */ - mysql->result->data->alloc.min_malloc=sizeof(MYSQL_ROWS); - mysql->result->data->rows=0; - mysql->result->data->fields=field_count; - mysql->result->field_count=field_count; - mysql->result->data->prev_ptr= &mysql->result->data->data; - - mysql->result->field_alloc= mysql->field_alloc; - mysql->result->current_field=0; - mysql->result->current_row=0; + thd->mysql->field_count= field_count; DBUG_RETURN(prepare_for_send(list)); err: @@ -456,13 +508,27 @@ send_eof(THD *thd, bool no_flush) void Protocol_simple::prepare_for_resend() { - MYSQL_ROWS *cur; - MYSQL_DATA *result= thd->mysql->result->data; + MYSQL_ROWS *cur; + MYSQL_DATA *data= thd->data; DBUG_ENTER("send_data"); - alloc= &result->alloc; - result->rows++; + if (!data) + { + if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + + alloc= &data->alloc; + init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */ + alloc->min_malloc=sizeof(MYSQL_ROWS); + data->rows=0; + data->fields=field_count; + data->prev_ptr= &data->data; + thd->data= data; + } + + data->rows++; if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *)))) { my_error(ER_OUT_OF_RESOURCES,MYF(0)); @@ -470,11 +536,11 @@ void Protocol_simple::prepare_for_resend() } cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS)); - *result->prev_ptr= cur; - result->prev_ptr= &cur->next; + *data->prev_ptr= cur; + data->prev_ptr= &cur->next; next_field=cur->data; - next_mysql_field= thd->mysql->result->fields; - + next_mysql_field= thd->mysql->fields; +err: DBUG_VOID_RETURN; } diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 579ff8eadbe..96e77aa340f 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -24,6 +24,7 @@ #include <sys/stat.h> #include <signal.h> #include <time.h> +#include "client_settings.h" #ifdef HAVE_PWD_H #include <pwd.h> #endif @@ -58,29 +59,11 @@ #define closesocket(A) close(A) #endif -void free_old_query(MYSQL *mysql); -my_bool STDCALL -emb_advanced_command(MYSQL *mysql, enum enum_server_command command, - const char *header, ulong header_length, - const char *arg, ulong arg_length, my_bool skip_check); - -/* From client.c */ -void mysql_read_default_options(struct st_mysql_options *options, - const char *filename,const char *group); -MYSQL * STDCALL -cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, - const char *passwd, const char *db, - uint port, const char *unix_socket,ulong client_flag); - -void STDCALL cli_mysql_close(MYSQL *mysql); - #ifdef HAVE_GETPWUID struct passwd *getpwuid(uid_t); char* getlogin(void); #endif -extern char server_inited; - #ifdef __WIN__ static my_bool is_NT(void) { @@ -165,77 +148,6 @@ static inline int mysql_init_charset(MYSQL *mysql) return 0; } -/************************************************************************** - Get column lengths of the current row - If one uses mysql_use_result, res->lengths contains the length information, - else the lengths are calculated from the offset between pointers. -**************************************************************************/ - -static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) -{ - MYSQL_ROW end; - - for (end=column + field_count; column != end ; column++,to++) - *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0; -} - -/************************************************************************** - List all fields in a table - If wild is given then only the fields matching wild is returned - Instead of this use query: - show fields in 'table' like "wild" -**************************************************************************/ - -static MYSQL_RES * STDCALL -emb_list_fields(MYSQL *mysql, const char *table, const char *wild) -{ - MYSQL_RES *result; - MYSQL_DATA *query; - char buff[257],*end; - DBUG_ENTER("mysql_list_fields"); - DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); - - LINT_INIT(query); - - end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); - if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1)) - DBUG_RETURN(NULL); - - result= mysql->result; - if (!result) - return 0; - - result->methods= mysql->methods; - result->eof=1; - - DBUG_RETURN(result); -} - -my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) -{ - stmt->fields= mysql->result->fields; - stmt->alloc; -} - -/* -** Note that the mysql argument must be initialized with mysql_init() -** before calling mysql_real_connect ! -*/ - -static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql); -static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql); -static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql); - -static MYSQL_METHODS embedded_methods= -{ - emb_mysql_read_query_result, - emb_advanced_command, - emb_mysql_store_result, - emb_mysql_use_result, - emb_fetch_lengths, - emb_list_fields -}; - MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, @@ -383,58 +295,3 @@ void STDCALL mysql_close(MYSQL *mysql) DBUG_VOID_RETURN; } -static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) -{ - if (mysql->net.last_errno) - return -1; - - if (mysql->field_count) - { - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->affected_rows= mysql->result->row_count= mysql->result->data->rows; - mysql->result->data_cursor= mysql->result->data->data; - } - - return 0; -} - -/************************************************************************** -** Alloc result struct for buffered results. All rows are read to buffer. -** mysql_data_seek may be used. -**************************************************************************/ -static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql) -{ - MYSQL_RES *result= mysql->result; - if (!result) - return 0; - - result->methods= mysql->methods; - mysql->result= NULL; - *result->data->prev_ptr= 0; - result->eof= 1; - result->lengths= (ulong*)(result + 1); - mysql->affected_rows= result->row_count= result->data->rows; - result->data_cursor= result->data->data; - - mysql->status=MYSQL_STATUS_READY; /* server is ready */ - return result; -} - -/************************************************************************** -** Alloc struct for use with unbuffered reads. Data is fetched by domand -** when calling to mysql_fetch_row. -** mysql_data_seek is a noop. -** -** No other queries may be specified with the same MYSQL handle. -** There shouldn't be much processing per row because mysql server shouldn't -** have to wait for the client (and will not wait more than 30 sec/packet). -**************************************************************************/ - -static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql) -{ - DBUG_ENTER("mysql_use_result"); - if (mysql->options.separate_thread) - DBUG_RETURN(0); - - DBUG_RETURN(emb_mysql_store_result(mysql)); -} |