diff options
-rw-r--r-- | include/mysql.h | 1 | ||||
-rw-r--r-- | include/sql_common.h | 7 | ||||
-rw-r--r-- | libmysql/client_settings.h | 1 | ||||
-rw-r--r-- | libmysql/libmysql.c | 69 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 43 | ||||
-rw-r--r-- | sql-common/client.c | 9 | ||||
-rw-r--r-- | sql/client_settings.h | 1 |
7 files changed, 97 insertions, 34 deletions
diff --git a/include/mysql.h b/include/mysql.h index c2f653e24d7..6ec64220706 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -560,6 +560,7 @@ typedef struct st_mysql_methods MYSQL_ROW column, uint field_count); MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql); my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); + int (STDCALL *stmt_execute)(MYSQL_STMT *stmt); } MYSQL_METHODS; MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query, diff --git a/include/sql_common.h b/include/sql_common.h index 1ca1b9b2348..1f442339c4f 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -34,6 +34,13 @@ void end_server(MYSQL *mysql); my_bool mysql_reconnect(MYSQL *mysql); void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group); +my_bool STDCALL +cli_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); + +void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, + const char *sqlstate); #ifdef __cplusplus } #endif diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index 2ad10bdc84c..9866c772d3a 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -54,3 +54,4 @@ MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql); my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt); MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, uint fields); +int STDCALL cli_stmt_execute(MYSQL_STMT *stmt); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 56b8a1a14e8..bfa7e4e9357 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1494,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode, Copy error message to statement handler */ -static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, - const char *sqlstate) +void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, + const char *sqlstate) { DBUG_ENTER("set_stmt_error_msg"); DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err)); @@ -1601,6 +1601,16 @@ my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) } stmt->field_count= (uint) field_count; stmt->param_count= (ulong) param_count; + if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, + sizeof(MYSQL_BIND)* + (stmt->param_count + + stmt->field_count)))) + { + set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); + DBUG_RETURN(1); + } + stmt->bind= stmt->params + stmt->param_count; + DBUG_RETURN(0); } @@ -1649,12 +1659,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) stmt_close(stmt, 1); DBUG_RETURN(0); } - if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, - sizeof(MYSQL_BIND)* - (stmt->param_count + - stmt->field_count)))) - set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); - stmt->bind= stmt->params + stmt->param_count; stmt->state= MY_ST_PREPARE; stmt->mysql= mysql; @@ -1975,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) mysql->last_used_con= mysql; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ - if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff, - MYSQL_STMT_HEADER, packet, - length, 1) || + if (cli_advanced_command(mysql, COM_EXECUTE, buff, + MYSQL_STMT_HEADER, packet, + length, 1) || mysql_read_query_result(mysql)) { set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } - stmt->state= MY_ST_EXECUTE; - mysql_free_result(stmt->result); - stmt->result= (MYSQL_RES *)0; - stmt->result_buffered= 0; - stmt->current_row= 0; DBUG_RETURN(0); } - -/* - Execute the prepare query -*/ - -int STDCALL mysql_execute(MYSQL_STMT *stmt) +int STDCALL cli_stmt_execute(MYSQL_STMT *stmt) { - DBUG_ENTER("mysql_execute"); + DBUG_ENTER("cli_stmt_execute"); - if (stmt->state == MY_ST_UNKNOWN) - { - set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); - DBUG_RETURN(1); - } if (stmt->param_count) { NET *net= &stmt->mysql->net; @@ -2065,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) DBUG_RETURN((int) execute(stmt,0,0)); } +/* + Execute the prepare query +*/ + +int STDCALL mysql_execute(MYSQL_STMT *stmt) +{ + DBUG_ENTER("mysql_execute"); + + if (stmt->state == MY_ST_UNKNOWN) + { + set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); + DBUG_RETURN(1); + } + if ((*stmt->mysql->methods->stmt_execute)(stmt)) + DBUG_RETURN(1); + + stmt->state= MY_ST_EXECUTE; + mysql_free_result(stmt->result); + stmt->result= (MYSQL_RES *)0; + stmt->result_buffered= 0; + stmt->current_row= 0; + DBUG_RETURN(0); +} + /* Return total parameters count in the statement diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 1d7f0e4db87..16a5b6b769c 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -100,7 +100,18 @@ emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), { MYSQL_DATA *result= ((THD*)mysql->thd)->data; if (!result) - return NULL; + { + if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + { + NET *net = &mysql->net; + net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->sqlstate, unknown_sqlstate); + strmov(net->last_error,ER(net->last_errno)); + return NULL; + } + return result; + } *result->prev_ptr= NULL; ((THD*)mysql->thd)->data= NULL; return result; @@ -126,6 +137,16 @@ static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) stmt->fields= mysql->fields; stmt->mem_root= mysql->field_alloc; } + + if (!(stmt->bind= + (MYSQL_BIND *) alloc_root(&stmt->mem_root, + sizeof(MYSQL_BIND)*stmt->field_count))) + { + set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); + return 1; + } + stmt->params= NULL; // we don't need parameter's buffer in embedded library + return 0; } @@ -154,6 +175,23 @@ static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) return 0; } +static int STDCALL emb_stmt_execute(MYSQL_STMT *stmt) +{ + DBUG_ENTER("emb_stmt_execute"); + THD *thd= (THD*)stmt->mysql->thd; + thd->client_param_count= stmt->param_count; + thd->client_parameters= stmt->params; + if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0, + (const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),1) + || emb_mysql_read_query_result(stmt->mysql)) + { + NET *net= &stmt->mysql->net; + set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + MYSQL_METHODS embedded_methods= { emb_mysql_read_query_result, @@ -162,7 +200,8 @@ MYSQL_METHODS embedded_methods= mysql_store_result, emb_fetch_lengths, emb_list_fields, - emb_read_prepare_result + emb_read_prepare_result, + emb_stmt_execute }; C_MODE_END diff --git a/sql-common/client.c b/sql-common/client.c index b3ddd64e111..73fe9e4663c 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -636,10 +636,10 @@ void free_rows(MYSQL_DATA *cur) } } -static my_bool STDCALL +my_bool STDCALL cli_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) + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check) { NET *net= &mysql->net; my_bool result= 1; @@ -1407,7 +1407,8 @@ static MYSQL_METHODS client_methods= cli_mysql_use_result, cli_fetch_lengths, cli_list_fields, - cli_read_prepare_result + cli_read_prepare_result, + cli_stmt_execute }; MYSQL * STDCALL diff --git a/sql/client_settings.h b/sql/client_settings.h index 97224d9890f..266f6807a36 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -34,4 +34,5 @@ #define cli_list_fields NULL #define cli_read_prepare_result NULL +#define cli_stmt_execute NULL |