From 94bfeb839399486eb90f2fc5dd25cdb4761d71bd Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 22 Jul 2004 20:54:25 +0500 Subject: Fixes for bugs in embedded library: #4700 (Unsigned value returned as signed) just no appropriate checking #4701 (Errors returned earlier than expected) all errors returned from send_command() #4702 (Result isn't freed properly if there's no retrieval) flush_use_result has only 'client' version and should be made 'virtual' --- include/mysql.h | 1 + include/sql_common.h | 1 - libmysql/libmysql.c | 4 ++-- libmysqld/lib_sql.cc | 22 +++++++++++++++++++++- sql-common/client.c | 7 ++++--- sql/sql_prepare.cc | 1 + 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index 0f3fdc90548..b339b839ab3 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -627,6 +627,7 @@ typedef struct st_mysql_methods MYSQL_RES * (*use_result)(MYSQL *mysql); void (*fetch_lengths)(unsigned long *to, MYSQL_ROW column, unsigned int field_count); + void (*flush_use_result)(MYSQL *mysql); #if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) MYSQL_FIELD * (*list_fields)(MYSQL *mysql); my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); diff --git a/include/sql_common.h b/include/sql_common.h index 3f50008a922..cde53786f83 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -25,7 +25,6 @@ extern "C" { MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, my_bool default_value, uint server_capabilities); void free_rows(MYSQL_DATA *cur); -void flush_use_result(MYSQL *mysql); my_bool mysql_autenticate(MYSQL *mysql, const char *passwd); void free_old_query(MYSQL *mysql); void end_server(MYSQL *mysql); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index fc7728c98e0..2b67d645d1a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4181,7 +4181,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt) if (mysql->status != MYSQL_STATUS_READY) { /* There is a result set and it belongs to this statement */ - flush_use_result(mysql); + (*mysql->methods->flush_use_result)(mysql); mysql->status= MYSQL_STATUS_READY; } } @@ -4231,7 +4231,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) Flush result set of the connection. If it does not belong to this statement, set a warning. */ - flush_use_result(mysql); + (*mysql->methods->flush_use_result)(mysql); if (mysql->unbuffered_fetch_owner) *mysql->unbuffered_fetch_owner= TRUE; mysql->status= MYSQL_STATUS_READY; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 0adf9aeb86a..e3d68fbb8eb 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -84,6 +84,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, thd->clear_error(); mysql->affected_rows= ~(my_ulonglong) 0; mysql->field_count= 0; + net->last_errno= 0; thd->store_globals(); // Fix if more than one connect /* @@ -107,17 +108,32 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (!skip_check) result= thd->net.last_errno ? -1 : 0; - embedded_get_error(mysql); + if (!mysql->field_count) + embedded_get_error(mysql); mysql->server_status= thd->server_status; mysql->warning_count= ((THD*)mysql->thd)->total_warn_count; return result; } +static void emb_flush_use_result(MYSQL *mysql) +{ + MYSQL_DATA *data= ((THD*)(mysql->thd))->data; + + if (data) + { + free_rows(data); + ((THD*)(mysql->thd))->data= NULL; + } +} + static MYSQL_DATA * emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), unsigned int fields __attribute__((unused))) { MYSQL_DATA *result= ((THD*)mysql->thd)->data; + embedded_get_error(mysql); + if (mysql->net.last_errno) + return NULL; if (!result) { if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), @@ -227,6 +243,9 @@ int emb_read_binary_rows(MYSQL_STMT *stmt) int emb_unbuffered_fetch(MYSQL *mysql, char **row) { MYSQL_DATA *data= ((THD*)mysql->thd)->data; + embedded_get_error(mysql); + if (mysql->net.last_errno) + return mysql->net.last_errno; if (!data || !data->data) { *row= NULL; @@ -293,6 +312,7 @@ MYSQL_METHODS embedded_methods= emb_read_rows, emb_mysql_store_result, emb_fetch_lengths, + emb_flush_use_result, emb_list_fields, emb_read_prepare_result, emb_stmt_execute, diff --git a/sql-common/client.c b/sql-common/client.c index 738904657cc..3046395f7d2 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -723,7 +723,7 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate) Flush result set sent from server */ -void flush_use_result(MYSQL *mysql) +static void cli_flush_use_result(MYSQL *mysql) { /* Clear the current execution status */ DBUG_PRINT("warning",("Not all packets read, clearing them")); @@ -842,7 +842,7 @@ mysql_free_result(MYSQL_RES *result) mysql->unbuffered_fetch_owner= 0; if (mysql->status == MYSQL_STATUS_USE_RESULT) { - flush_use_result(mysql); + (*mysql->methods->flush_use_result)(mysql); mysql->status=MYSQL_STATUS_READY; } } @@ -1493,7 +1493,8 @@ static MYSQL_METHODS client_methods= cli_advanced_command, cli_read_rows, cli_use_result, - cli_fetch_lengths + cli_fetch_lengths, + cli_flush_use_result #ifndef MYSQL_SERVER ,cli_list_fields, cli_read_prepare_result, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4305bee42a2..47cc461fac0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -696,6 +696,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) else { uchar *buff= (uchar*) client_param->buffer; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1 From 50183677ccbca1692e9524d077cc749034b18209 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 23 Jul 2004 00:00:50 +0500 Subject: Several fixes to make tests working for embedded library --- libmysqld/lib_sql.cc | 19 ++++++++----------- sql/mysqld.cc | 2 ++ sql/set_var.cc | 2 ++ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index e3d68fbb8eb..5ecea557361 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -462,14 +462,6 @@ int init_embedded_server(int argc, char **argv, char **groups) } } - /* - Update mysqld variables from client variables if set - The client variables are set also by get_one_option() in mysqld.cc - */ - if (max_allowed_packet) - global_system_variables.max_allowed_packet= max_allowed_packet; - if (net_buffer_length) - global_system_variables.net_buffer_length= net_buffer_length; return 0; } @@ -498,18 +490,20 @@ void *create_embedded_thd(int client_flag, char *db) if (thd->store_globals()) { fprintf(stderr,"store_globals failed.\n"); - return NULL; + goto err; } thd->mysys_var= my_thread_var; thd->dbug_thread_id= my_thread_id(); thd->thread_stack= (char*) &thd; +/* TODO - add init_connect command execution */ + thd->proc_info=0; // Remove 'login' thd->command=COM_SLEEP; thd->version=refresh_version; thd->set_time(); - init_sql_alloc(&thd->mem_root,8192,8192); + thd->init_for_queries(); thd->client_capabilities= client_flag; thd->db= db; @@ -524,6 +518,9 @@ void *create_embedded_thd(int client_flag, char *db) thread_count++; return thd; +err: + delete(thd); + return NULL; } #ifdef NO_EMBEDDED_ACCESS_CHECKS @@ -629,7 +626,7 @@ bool Protocol::send_fields(List *list, uint flag) client_field->org_table_length= strlen(client_field->org_table); client_field->charsetnr= server_field.charsetnr; - client_field->catalog= strdup_root(field_alloc, "std"); + client_field->catalog= strdup_root(field_alloc, "def"); client_field->catalog_length= 3; if (INTERNAL_NUM_FIELD(client_field)) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4fd13d33bab..27e9c5127f8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5583,9 +5583,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #ifdef EMBEDDED_LIBRARY case OPT_MAX_ALLOWED_PACKET: max_allowed_packet= atoi(argument); + global_system_variables.max_allowed_packet= max_allowed_packet; break; case OPT_NET_BUFFER_LENGTH: net_buffer_length= atoi(argument); + global_system_variables.net_buffer_length= net_buffer_length; break; #endif #include diff --git a/sql/set_var.cc b/sql/set_var.cc index e1cfb77d297..1bd45cccda3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1129,8 +1129,10 @@ static int check_max_delayed_threads(THD *thd, set_var *var) static void fix_max_connections(THD *thd, enum_var_type type) { +#ifndef EMBEDDED_LIBRARY resize_thr_alarm(max_connections + global_system_variables.max_insert_delayed_threads + 10); +#endif } -- cgit v1.2.1 From 0ce4b28b5ed848a9e6ee419f91f2bf5d40e98417 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 19 Aug 2004 15:36:05 +0500 Subject: addition to fixes about #4700, 4701 --- libmysqld/lib_sql.cc | 6 ++++++ sql/sql_prepare.cc | 1 + 2 files changed, 7 insertions(+) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 5ecea557361..51a723d225a 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -108,6 +108,12 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (!skip_check) result= thd->net.last_errno ? -1 : 0; + /* + If mysql->field_count is set it means the parsing of the query was OK + and metadata was returned (see Protocol::send_fields). + In this case we postpone the error to be returned in mysql_stmt_store_result + (see emb_read_rows) to behave just as standalone server. + */ if (!mysql->field_count) embedded_get_error(mysql); mysql->server_status= thd->server_status; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 47cc461fac0..754da84f257 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -737,6 +737,7 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) else { uchar *buff= (uchar*)client_param->buffer; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1 From 69ee037e292e66987882a631dd7c971507db36dc Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 19 Aug 2004 15:38:12 +0500 Subject: Small tab's cleanup --- sql/sql_prepare.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 754da84f257..b9f626ce8d4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -696,7 +696,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) else { uchar *buff= (uchar*) client_param->buffer; - param->unsigned_flag= client_param->is_unsigned; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1