diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 2e851f52032..4f5aaba0f8e 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -261,6 +261,7 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size #define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt) TSRMLS_CC) #define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit) TSRMLS_CC) #define mysqlnd_stmt_reset(stmt) (stmt)->m->reset((stmt) TSRMLS_CC) +#define mysqlnd_stmt_flush(stmt) (stmt)->m->flush((stmt) TSRMLS_CC) #define mysqlnd_stmt_attr_get(stmt, attr, value) (stmt)->m->get_attribute((stmt), (attr), (value) TSRMLS_CC) diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index ef1a0082703..237c088ac4b 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -628,27 +628,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) } #endif - /* - If right after execute() we have to call the appropriate - use_result() or store_result() and clean. - */ - if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { - DBG_INF("fetching result set header"); - /* Do implicit use_result and then flush the result */ - stmt->default_rset_handler = s->m->use_result; - stmt->default_rset_handler(s TSRMLS_CC); - } - - if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE) { - DBG_INF("skipping result"); - /* Flush if anything is left and unbuffered set */ - stmt->result->m.skip_result(stmt->result TSRMLS_CC); - } - - if (stmt->state > MYSQLND_STMT_PREPARED) { - /* As the buffers have been freed, we should go back to PREPARED */ - stmt->state = MYSQLND_STMT_PREPARED; - } + s->m->flush(s TSRMLS_CC); /* Executed, but the user hasn't started to fetch @@ -1228,6 +1208,45 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) } } + s->m->flush(s TSRMLS_CC); + + /* + Don't free now, let the result be usable. When the stmt will again be + executed then the result set will be cleaned, the bound variables will + be separated before that. + */ + + int4store(cmd_buf, stmt->stmt_id); + if (CONN_GET_STATE(conn) == CONN_READY && + FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf, + sizeof(cmd_buf), PROT_OK_PACKET, + FALSE, TRUE TSRMLS_CC))) { + stmt->error_info = conn->error_info; + } + stmt->upsert_status = conn->upsert_status; + + stmt->state = MYSQLND_STMT_PREPARED; + } + DBG_INF(ret == PASS? "PASS":"FAIL"); + DBG_RETURN(ret); +} +/* }}} */ + + +/* {{{ mysqlnd_stmt::flush */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_stmt, flush)(MYSQLND_STMT * const s TSRMLS_DC) +{ + MYSQLND_STMT_DATA * stmt = s? s->data:NULL; + enum_func_status ret = PASS; + + DBG_ENTER("mysqlnd_stmt::flush"); + if (!stmt || !stmt->conn) { + DBG_RETURN(FAIL); + } + DBG_INF_FMT("stmt=%lu", stmt->stmt_id); + + if (stmt->stmt_id) { /* If the user decided to close the statement right after execute() We have to call the appropriate use_result() or store_result() and @@ -1246,21 +1265,6 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) } } while (mysqlnd_stmt_more_results(s) && mysqlnd_stmt_next_result(s) == PASS); - /* - Don't free now, let the result be usable. When the stmt will again be - executed then the result set will be cleaned, the bound variables will - be separated before that. - */ - - int4store(cmd_buf, stmt->stmt_id); - if (CONN_GET_STATE(conn) == CONN_READY && - FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf, - sizeof(cmd_buf), PROT_OK_PACKET, - FALSE, TRUE TSRMLS_CC))) { - stmt->error_info = conn->error_info; - } - stmt->upsert_status = conn->upsert_status; - stmt->state = MYSQLND_STMT_PREPARED; } DBG_INF(ret == PASS? "PASS":"FAIL"); @@ -2335,7 +2339,8 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_stmt) MYSQLND_METHOD(mysqlnd_stmt, server_status), mysqlnd_stmt_execute_generate_request, mysqlnd_stmt_execute_parse_response, - MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content) + MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content), + MYSQLND_METHOD(mysqlnd_stmt, flush) MYSQLND_CLASS_METHODS_END; diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 5afd8eae04b..c5bdb1fd0b7 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -641,6 +641,7 @@ typedef unsigned int (*func_mysqlnd_stmt__server_status)(const MYSQLND_STMT * c typedef enum_func_status (*func_mysqlnd_stmt__generate_execute_request)(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__parse_execute_response)(MYSQLND_STMT * const s TSRMLS_DC); typedef void (*func_mysqlnd_stmt__free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC); +typedef enum_func_status (*func_mysqlnd_stmt__flush)(MYSQLND_STMT * const stmt TSRMLS_DC); struct st_mysqlnd_stmt_methods { @@ -694,6 +695,8 @@ struct st_mysqlnd_stmt_methods func_mysqlnd_stmt__parse_execute_response parse_execute_response; func_mysqlnd_stmt__free_stmt_content free_stmt_content; + + func_mysqlnd_stmt__flush flush; };