summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/mysqlnd/mysqlnd.c390
-rw-r--r--ext/mysqlnd/mysqlnd_priv.h5
-rw-r--r--ext/mysqlnd/mysqlnd_ps.c104
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h6
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c14
5 files changed, 478 insertions, 41 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 3026b67c1f..a4a5294f40 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -32,10 +32,6 @@
extern MYSQLND_CHARSET *mysqlnd_charsets;
-
-struct st_mysqlnd_protocol_command *
-mysqlnd_get_command(enum php_mysqlnd_server_command command, ...);
-
PHPAPI const char * const mysqlnd_old_passwd = "mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. "
"Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will "
"store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords "
@@ -351,26 +347,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_do_request)(MYSQLND_CONN_DATA * c
/* }}} */
-/* {{{ mysqlnd_conn_data::simple_command */
-static enum_func_status
-MYSQLND_METHOD(mysqlnd_conn_data, send_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
- const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent,
- zend_bool ignore_upsert_status)
-{
- enum_func_status ret;
- DBG_ENTER("mysqlnd_conn_data::send_command");
-
- ret = conn->m->send_command_do_request(conn, command, arg, arg_len, silent, ignore_upsert_status);
- if (PASS == ret && ok_packet != PROT_LAST) {
- ret = conn->m->send_command_handle_response(conn, ok_packet, silent, command, ignore_upsert_status);
- }
-
- DBG_INF(ret == PASS ? "PASS":"FAIL");
- DBG_RETURN(ret);
-}
-/* }}} */
-
-
/* {{{ mysqlnd_conn_data::set_server_option */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, set_server_option)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_server_option option)
@@ -3053,7 +3029,7 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, get_state),
MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, set_state),
- MYSQLND_METHOD(mysqlnd_conn_data, send_command),
+ MYSQLND_METHOD(mysqlnd_conn_data, send_command_do_request),
MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response),
MYSQLND_METHOD(mysqlnd_conn_data, restart_psession),
MYSQLND_METHOD(mysqlnd_conn_data, end_psession),
@@ -3075,7 +3051,6 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands),
MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags),
MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake),
- MYSQLND_METHOD(mysqlnd_conn_data, send_command_do_request),
MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name),
MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d),
@@ -3746,6 +3721,56 @@ mysqlnd_com_query_create_command(va_list args)
}
/* }}} */
+/************************** COM_CHANGE_USER ******************************************/
+struct st_mysqlnd_protocol_com_change_user_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_change_user_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ zend_bool silent;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_change_user_run */
+static enum_func_status
+mysqlnd_com_change_user_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_change_user_command * command = (struct st_mysqlnd_protocol_com_change_user_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_change_user_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_CHANGE_USER, (zend_uchar*) command->context.payload.s, command->context.payload.l, command->context.silent, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_change_user_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_change_user_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_change_user_command * command;
+ DBG_ENTER("mysqlnd_com_change_user_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_change_user_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+ command->context.silent = va_arg(args, unsigned int);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_change_user_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
/************************** COM_REAP_RESULT ******************************************/
struct st_mysqlnd_protocol_com_reap_result_command
@@ -3799,6 +3824,298 @@ mysqlnd_com_reap_result_create_command(va_list args)
/* }}} */
+/************************** COM_STMT_PREPARE ******************************************/
+struct st_mysqlnd_protocol_com_stmt_prepare_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_prepare_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING query;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_prepare_run */
+static enum_func_status
+mysqlnd_com_stmt_prepare_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_prepare_command * command = (struct st_mysqlnd_protocol_com_stmt_prepare_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_prepare_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_PREPARE, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_prepare_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_prepare_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_prepare_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_prepare_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_prepare_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.query = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_prepare_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
+
+/************************** COM_STMT_EXECUTE ******************************************/
+struct st_mysqlnd_protocol_com_stmt_execute_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_execute_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_execute_run */
+static enum_func_status
+mysqlnd_com_stmt_execute_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_execute_command * command = (struct st_mysqlnd_protocol_com_stmt_execute_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_execute_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_EXECUTE, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, FALSE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_execute_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_execute_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_execute_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_execute_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_execute_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_execute_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
+
+/************************** COM_STMT_FETCH ******************************************/
+struct st_mysqlnd_protocol_com_stmt_fetch_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_fetch_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_fetch_run */
+static enum_func_status
+mysqlnd_com_stmt_fetch_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_fetch_command * command = (struct st_mysqlnd_protocol_com_stmt_fetch_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_fetch_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_FETCH, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_fetch_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_fetch_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_fetch_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_fetch_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_fetch_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_fetch_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
+
+/************************** COM_STMT_RESET ******************************************/
+struct st_mysqlnd_protocol_com_stmt_reset_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_reset_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_reset_run */
+static enum_func_status
+mysqlnd_com_stmt_reset_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_reset_command * command = (struct st_mysqlnd_protocol_com_stmt_reset_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_reset_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_RESET, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_reset_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_reset_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_reset_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_reset_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_reset_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_reset_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
+
+/************************** COM_STMT_SEND_LONG_DATA ******************************************/
+struct st_mysqlnd_protocol_com_stmt_send_long_data_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_send_long_data_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_send_long_data_run */
+static enum_func_status
+mysqlnd_com_stmt_send_long_data_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_send_long_data_command * command = (struct st_mysqlnd_protocol_com_stmt_send_long_data_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_send_long_data_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_SEND_LONG_DATA, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_send_long_data_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_send_long_data_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_send_long_data_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_send_long_data_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_send_long_data_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_send_long_data_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
+
+
+/************************** COM_STMT_CLOSE ******************************************/
+struct st_mysqlnd_protocol_com_stmt_close_command
+{
+ struct st_mysqlnd_protocol_command parent;
+ struct st_mysqlnd_com_stmt_close_context
+ {
+ MYSQLND_CONN_DATA * conn;
+ MYSQLND_CSTRING payload;
+ } context;
+};
+
+
+/* {{{ mysqlnd_com_stmt_close_run */
+static enum_func_status
+mysqlnd_com_stmt_close_run(void *cmd)
+{
+ struct st_mysqlnd_protocol_com_stmt_close_command * command = (struct st_mysqlnd_protocol_com_stmt_close_command *) cmd;
+ enum_func_status ret = FAIL;
+ MYSQLND_CONN_DATA * conn = command->context.conn;
+
+ DBG_ENTER("mysqlnd_com_stmt_close_run");
+
+ ret = conn->m->send_command_do_request(conn, COM_STMT_CLOSE, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE);
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_com_stmt_close_create_command */
+static struct st_mysqlnd_protocol_command *
+mysqlnd_com_stmt_close_create_command(va_list args)
+{
+ struct st_mysqlnd_protocol_com_stmt_close_command * command;
+ DBG_ENTER("mysqlnd_com_stmt_close_create_command");
+ command = mnd_ecalloc(1, sizeof(struct st_mysqlnd_protocol_com_stmt_close_command));
+ if (command) {
+ command->context.conn = va_arg(args, MYSQLND_CONN_DATA *);
+ command->context.payload = va_arg(args, MYSQLND_CSTRING);
+
+ command->parent.free_command = mysqlnd_com_no_params_free_command;
+ command->parent.run = mysqlnd_com_stmt_close_run;
+ }
+
+ DBG_RETURN((struct st_mysqlnd_protocol_command *) command);
+}
+/* }}} */
/* {{{ mysqlnd_get_command */
@@ -3847,6 +4164,27 @@ mysqlnd_get_command(enum php_mysqlnd_server_command command, ...)
case COM_REAP_RESULT:
ret = mysqlnd_com_reap_result_create_command(args);
break;
+ case COM_CHANGE_USER:
+ ret = mysqlnd_com_change_user_create_command(args);
+ break;
+ case COM_STMT_PREPARE:
+ ret = mysqlnd_com_stmt_prepare_create_command(args);
+ break;
+ case COM_STMT_EXECUTE:
+ ret = mysqlnd_com_stmt_execute_create_command(args);
+ break;
+ case COM_STMT_FETCH:
+ ret = mysqlnd_com_stmt_fetch_create_command(args);
+ break;
+ case COM_STMT_RESET:
+ ret = mysqlnd_com_stmt_reset_create_command(args);
+ break;
+ case COM_STMT_SEND_LONG_DATA:
+ ret = mysqlnd_com_stmt_send_long_data_create_command(args);
+ break;
+ case COM_STMT_CLOSE:
+ ret = mysqlnd_com_stmt_close_create_command(args);
+ break;
default:
break;
}
diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h
index 618845afff..831b30d13f 100644
--- a/ext/mysqlnd/mysqlnd_priv.h
+++ b/ext/mysqlnd/mysqlnd_priv.h
@@ -240,6 +240,11 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
size_t * switch_to_auth_protocol_data_len
);
+/* {{{ mysqlnd_get_command */
+struct st_mysqlnd_protocol_command *
+mysqlnd_get_command(enum php_mysqlnd_server_command command, ...);
+
+
#endif /* MYSQLND_PRIV_H */
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c
index 5d79216c97..6a94f06c47 100644
--- a/ext/mysqlnd/mysqlnd_ps.c
+++ b/ext/mysqlnd/mysqlnd_ps.c
@@ -417,7 +417,23 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
stmt_to_prepare = s_to_prepare->data;
}
- if (FAIL == stmt_to_prepare->conn->m->send_command(stmt_to_prepare->conn, COM_STMT_PREPARE, (const zend_uchar *) query, query_len, PROT_LAST, FALSE, TRUE) ||
+ {
+ enum_func_status ret = FAIL;
+ const MYSQLND_CSTRING query_string = {query, query_len};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_PREPARE, stmt_to_prepare->conn, query_string);
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+ }
+ if (FAIL == ret) {
+ goto fail;
+ }
+ }
+
+ if (
+#if A0
+ FAIL == stmt_to_prepare->conn->m->send_command(stmt_to_prepare->conn, COM_STMT_PREPARE, (const zend_uchar *) query, query_len, PROT_LAST, FALSE, TRUE) ||
+#endif
FAIL == mysqlnd_stmt_read_prepare_response(s_to_prepare))
{
goto fail;
@@ -722,10 +738,19 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, enum_mysqlnd_
}
ret = s->m->generate_execute_request(s, &request, &request_len, &free_request);
if (ret == PASS) {
+ const MYSQLND_CSTRING payload = {request, request_len};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_EXECUTE, stmt->conn, payload);
+ ret = FAIL;
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+ }
+#if A0
/* support for buffer types should be added here ! */
ret = stmt->conn->m->send_command(stmt->conn, COM_STMT_EXECUTE, request, request_len,
PROT_LAST /* we will handle the response packet*/,
FALSE, FALSE);
+#endif
} else {
SET_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Couldn't generate the request. Possibly OOM.");
}
@@ -1057,12 +1082,30 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
int4store(buf, stmt->stmt_id);
int4store(buf + STMT_ID_LENGTH, 1); /* for now fetch only one row */
+ {
+ const MYSQLND_CSTRING payload = {buf, sizeof(buf)};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_FETCH, stmt->conn, payload);
+ ret = FAIL;
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+ if (ret == FAIL) {
+ COPY_CLIENT_ERROR(*stmt->error_info, *stmt->conn->error_info);
+ }
+ }
+ if (FAIL == ret) {
+ DBG_RETURN(FAIL);
+ }
+
+ }
+#if A9
if (FAIL == stmt->conn->m->send_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf),
PROT_LAST /* we will handle the response packet*/,
FALSE, TRUE)) {
COPY_CLIENT_ERROR(*stmt->error_info, *stmt->conn->error_info);
DBG_RETURN(FAIL);
}
+#endif
row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE;
@@ -1263,12 +1306,30 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s)
*/
int4store(cmd_buf, stmt->stmt_id);
+
+ if (CONN_GET_STATE(conn) == CONN_READY) {
+ const MYSQLND_CSTRING payload = {cmd_buf, sizeof(cmd_buf)};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_RESET, stmt->conn, payload);
+ ret = FAIL;
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+
+ if (ret == PASS) {
+ ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE);
+ } else {
+ COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
+ }
+ }
+ }
+#if A0
if (CONN_GET_STATE(conn) == CONN_READY &&
FAIL == (ret = conn->m->send_command(conn, COM_STMT_RESET, cmd_buf,
sizeof(cmd_buf), PROT_OK_PACKET,
FALSE, TRUE))) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
}
+#endif
*stmt->upsert_status = *conn->upsert_status;
}
DBG_INF(ret == PASS? "PASS":"FAIL");
@@ -1324,7 +1385,6 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
enum_func_status ret = FAIL;
MYSQLND_CONN_DATA * conn;
zend_uchar * cmd_buf;
- enum php_mysqlnd_server_command cmd = COM_STMT_SEND_LONG_DATA;
DBG_ENTER("mysqlnd_stmt::send_long_data");
if (!stmt || !stmt->conn) {
@@ -1379,11 +1439,26 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
memcpy(cmd_buf + STMT_ID_LENGTH + 2, data, length);
/* COM_STMT_SEND_LONG_DATA doesn't send an OK packet*/
- ret = conn->m->send_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE);
- mnd_efree(cmd_buf);
+ {
+ const MYSQLND_CSTRING payload = {cmd_buf, packet_len};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_SEND_LONG_DATA, stmt->conn, payload);
+ ret = FAIL;
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+ if (ret == FAIL) {
+ COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
+ }
+ }
+ }
+
+#if A0
+ ret = conn->m->send_command(conn, COM_STMT_SEND_LONG_DATA, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE);
if (FAIL == ret) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
}
+#endif
+ mnd_efree(cmd_buf);
} else {
ret = FAIL;
SET_OOM_ERROR(*stmt->error_info);
@@ -1409,7 +1484,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
#if HAVE_USLEEP && !defined(PHP_WIN32)
usleep(120000);
#endif
- if ((packet_len = conn->net->m.consume_uneaten_data(conn->net, cmd))) {
+ if ((packet_len = conn->net->m.consume_uneaten_data(conn->net, COM_STMT_SEND_LONG_DATA))) {
php_error_docref(NULL, E_WARNING, "There was an error "
"while sending long data. Probably max_allowed_packet_size "
"is smaller than the data. You have to increase it or send "
@@ -2198,12 +2273,29 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
STAT_FREE_RESULT_EXPLICIT);
int4store(cmd_buf, stmt->stmt_id);
- if (CONN_GET_STATE(conn) == CONN_READY &&
+ if (CONN_GET_STATE(conn) == CONN_READY) {
+ enum_func_status ret = FAIL;
+ const MYSQLND_CSTRING payload = {cmd_buf, sizeof(cmd_buf)};
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_STMT_CLOSE, conn, payload);
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
+
+ if (ret == FAIL) {
+ COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
+ }
+ }
+ if (ret == FAIL) {
+ DBG_RETURN(FAIL);
+ }
+
+#if A0
FAIL == conn->m->send_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf),
PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,
FALSE, TRUE)) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
DBG_RETURN(FAIL);
+#endif
}
}
switch (stmt->execute_count) {
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index 05c5821694..9489f1d2c7 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -476,7 +476,7 @@ typedef enum_func_status (*func_mysqlnd_conn_data__free_reference)(MYSQLND_CONN_
typedef enum mysqlnd_connection_state (*func_mysqlnd_conn_data__get_state)(const MYSQLND_CONN_DATA * const conn);
typedef void (*func_mysqlnd_conn_data__set_state)(MYSQLND_CONN_DATA * const conn, enum mysqlnd_connection_state new_state);
-typedef enum_func_status (*func_mysqlnd_conn_data__send_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent, zend_bool ignore_upsert_status);
+typedef enum_func_status (*func_mysqlnd_conn_data__send_command_do_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status);
typedef enum_func_status (*func_mysqlnd_conn_data__send_command_handle_response)(MYSQLND_CONN_DATA * conn, enum mysqlnd_packet_type ok_packet, zend_bool silent, enum php_mysqlnd_server_command command, zend_bool ignore_upsert_status);
typedef enum_func_status (*func_mysqlnd_conn_data__restart_psession)(MYSQLND_CONN_DATA * conn);
@@ -501,7 +501,6 @@ typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DA
typedef enum_func_status (*func_mysqlnd_conn_data__execute_init_commands)(MYSQLND_CONN_DATA * conn);
typedef unsigned int (*func_mysqlnd_conn_data__get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags);
typedef enum_func_status (*func_mysqlnd_conn_data__connect_handshake)(MYSQLND_CONN_DATA * conn, const char * const host, const char * const user, const char * const passwd, const unsigned int passwd_len, const char * const db, const unsigned int db_len, const unsigned int mysql_flags);
-typedef enum_func_status (*func_mysqlnd_conn_data__send_command_do_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status);
typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetch_auth_plugin_by_name)(const char * const requested_protocol);
typedef enum_func_status (*func_mysqlnd_conn_data__set_client_option_2d)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_client_option option, const char * const key, const char * const value);
@@ -572,7 +571,7 @@ struct st_mysqlnd_conn_data_methods
func_mysqlnd_conn_data__get_state get_state;
func_mysqlnd_conn_data__set_state set_state;
- func_mysqlnd_conn_data__send_command send_command;
+ func_mysqlnd_conn_data__send_command_do_request send_command_do_request;
func_mysqlnd_conn_data__send_command_handle_response send_command_handle_response;
func_mysqlnd_conn_data__restart_psession restart_psession;
@@ -597,7 +596,6 @@ struct st_mysqlnd_conn_data_methods
func_mysqlnd_conn_data__execute_init_commands execute_init_commands;
func_mysqlnd_conn_data__get_updated_connect_flags get_updated_connect_flags;
func_mysqlnd_conn_data__connect_handshake connect_handshake;
- func_mysqlnd_conn_data__send_command_do_request send_command_do_request;
func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;
func_mysqlnd_conn_data__set_client_option_2d set_client_option_2d;
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index a67e583d05..b37ffe8dbb 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -655,12 +655,16 @@ size_t php_mysqlnd_auth_write(void * _packet)
}
}
if (packet->is_change_user_packet) {
- if (PASS != conn->m->send_command(conn, COM_CHANGE_USER, buffer + MYSQLND_HEADER_SIZE, p - buffer - MYSQLND_HEADER_SIZE,
- PROT_LAST /* the caller will handle the OK packet */,
- packet->silent, TRUE)) {
- DBG_RETURN(0);
+ enum_func_status ret = FAIL;
+ const MYSQLND_CSTRING payload = {buffer + MYSQLND_HEADER_SIZE, p - (buffer + MYSQLND_HEADER_SIZE)};
+ const unsigned int silent = packet->silent;
+ struct st_mysqlnd_protocol_command * command = mysqlnd_get_command(COM_CHANGE_USER, conn, payload, silent);
+ if (command) {
+ ret = command->run(command);
+ command->free_command(command);
}
- DBG_RETURN(p - buffer - MYSQLND_HEADER_SIZE);
+
+ DBG_RETURN(ret == PASS? (p - buffer - MYSQLND_HEADER_SIZE) : 0);
} else {
size_t sent = conn->net->data->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info);
if (!sent) {