summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysql.h1
-rw-r--r--include/sql_common.h7
-rw-r--r--libmysql/client_settings.h1
-rw-r--r--libmysql/libmysql.c69
-rw-r--r--libmysqld/lib_sql.cc43
-rw-r--r--sql-common/client.c9
-rw-r--r--sql/client_settings.h1
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