mirror of
https://github.com/php/php-src.git
synced 2024-12-13 03:44:17 +08:00
Fixed bug #49027 (mysqli_options() doesn't work when using mysqlnd)
This commit is contained in:
parent
2e92372322
commit
149914f644
28
ext/mysqli/tests/bug49027.phpt
Normal file
28
ext/mysqli/tests/bug49027.phpt
Normal file
@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #49027 (mysqli_options() doesn't work when using mysqlnd)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
include ("connect.inc");
|
||||
|
||||
$link=mysqli_init();
|
||||
if (!mysqli_options($link, MYSQLI_INIT_COMMAND, "SELECT 1")){
|
||||
echo "Broken 2!\n";
|
||||
}
|
||||
if (!mysqli_options($link, MYSQLI_INIT_COMMAND, "SELECT 13")){
|
||||
echo "Broken 2!\n";
|
||||
}
|
||||
|
||||
require('table_real_connect.inc');
|
||||
|
||||
var_dump($link->query("SELECT 42")->fetch_row());
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
%unicode|string%(2) "42"
|
||||
}
|
23
ext/mysqli/tests/table_real_connect.inc
Normal file
23
ext/mysqli/tests/table_real_connect.inc
Normal file
@ -0,0 +1,23 @@
|
||||
<?PHP
|
||||
require_once('connect.inc');
|
||||
|
||||
if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
|
||||
printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) {
|
||||
printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')")) {
|
||||
printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
}
|
||||
?>
|
@ -82,6 +82,56 @@ void mysqlnd_library_end(TSRMLS_D)
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn::free_options */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_conn, free_options)(MYSQLND *conn TSRMLS_DC)
|
||||
{
|
||||
zend_bool pers = conn->persistent;
|
||||
|
||||
if (conn->options.charset_name) {
|
||||
mnd_pefree(conn->options.charset_name, pers);
|
||||
conn->options.charset_name = NULL;
|
||||
}
|
||||
if (conn->options.num_commands) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < conn->options.num_commands; i++) {
|
||||
/* allocated with pestrdup */
|
||||
pefree(conn->options.init_commands[i], pers);
|
||||
}
|
||||
mnd_pefree(conn->options.init_commands, pers);
|
||||
conn->options.init_commands = NULL;
|
||||
}
|
||||
if (conn->options.cfg_file) {
|
||||
mnd_pefree(conn->options.cfg_file, pers);
|
||||
conn->options.cfg_file = NULL;
|
||||
}
|
||||
if (conn->options.cfg_section) {
|
||||
mnd_pefree(conn->options.cfg_section, pers);
|
||||
conn->options.cfg_section = NULL;
|
||||
}
|
||||
if (conn->options.ssl_key) {
|
||||
mnd_pefree(conn->options.ssl_key, pers);
|
||||
conn->options.ssl_key = NULL;
|
||||
}
|
||||
if (conn->options.ssl_cert) {
|
||||
mnd_pefree(conn->options.ssl_cert, pers);
|
||||
conn->options.ssl_cert = NULL;
|
||||
}
|
||||
if (conn->options.ssl_ca) {
|
||||
mnd_pefree(conn->options.ssl_ca, pers);
|
||||
conn->options.ssl_ca = NULL;
|
||||
}
|
||||
if (conn->options.ssl_capath) {
|
||||
mnd_pefree(conn->options.ssl_capath, pers);
|
||||
conn->options.ssl_capath = NULL;
|
||||
}
|
||||
if (conn->options.ssl_cipher) {
|
||||
mnd_pefree(conn->options.ssl_cipher, pers);
|
||||
conn->options.ssl_cipher = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn::free_contents */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC)
|
||||
@ -153,46 +203,6 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC)
|
||||
mnd_pefree(conn->last_message, pers);
|
||||
conn->last_message = NULL;
|
||||
}
|
||||
if (conn->options.charset_name) {
|
||||
mnd_pefree(conn->options.charset_name, pers);
|
||||
conn->options.charset_name = NULL;
|
||||
}
|
||||
if (conn->options.num_commands) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < conn->options.num_commands; i++) {
|
||||
mnd_pefree(conn->options.init_commands[i], pers);
|
||||
}
|
||||
mnd_pefree(conn->options.init_commands, pers);
|
||||
conn->options.init_commands = NULL;
|
||||
}
|
||||
if (conn->options.cfg_file) {
|
||||
mnd_pefree(conn->options.cfg_file, pers);
|
||||
conn->options.cfg_file = NULL;
|
||||
}
|
||||
if (conn->options.cfg_section) {
|
||||
mnd_pefree(conn->options.cfg_section, pers);
|
||||
conn->options.cfg_section = NULL;
|
||||
}
|
||||
if (conn->options.ssl_key) {
|
||||
mnd_pefree(conn->options.ssl_key, pers);
|
||||
conn->options.ssl_key = NULL;
|
||||
}
|
||||
if (conn->options.ssl_cert) {
|
||||
mnd_pefree(conn->options.ssl_cert, pers);
|
||||
conn->options.ssl_cert = NULL;
|
||||
}
|
||||
if (conn->options.ssl_ca) {
|
||||
mnd_pefree(conn->options.ssl_ca, pers);
|
||||
conn->options.ssl_ca = NULL;
|
||||
}
|
||||
if (conn->options.ssl_capath) {
|
||||
mnd_pefree(conn->options.ssl_capath, pers);
|
||||
conn->options.ssl_capath = NULL;
|
||||
}
|
||||
if (conn->options.ssl_cipher) {
|
||||
mnd_pefree(conn->options.ssl_cipher, pers);
|
||||
conn->options.ssl_cipher = NULL;
|
||||
}
|
||||
if (conn->zval_cache) {
|
||||
DBG_INF("Freeing zval cache reference");
|
||||
mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache);
|
||||
@ -229,6 +239,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor)(MYSQLND *conn TSRMLS_DC)
|
||||
DBG_INF_FMT("conn=%llu", conn->thread_id);
|
||||
|
||||
conn->m->free_contents(conn TSRMLS_CC);
|
||||
conn->m->free_options(conn TSRMLS_CC);
|
||||
|
||||
#ifdef MYSQLND_THREADED
|
||||
if (conn->thread_is_running) {
|
||||
@ -736,10 +747,6 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn,
|
||||
|
||||
SET_EMPTY_ERROR(conn->error_info);
|
||||
|
||||
PACKET_FREE_ALLOCA(greet_packet);
|
||||
PACKET_FREE(auth_packet);
|
||||
PACKET_FREE_ALLOCA(ok_packet);
|
||||
|
||||
conn->zval_cache = mysqlnd_palloc_get_thd_cache_reference(zval_cache);
|
||||
conn->net.cmd_buffer.length = 128L*1024L;
|
||||
conn->net.cmd_buffer.buffer = mnd_pemalloc(conn->net.cmd_buffer.length, conn->persistent);
|
||||
@ -791,6 +798,25 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (conn->options.init_commands) {
|
||||
int current_command = 0;
|
||||
for (; current_command < conn->options.num_commands; ++current_command) {
|
||||
const char * const command = conn->options.init_commands[current_command];
|
||||
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT);
|
||||
if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) {
|
||||
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_FAILED_COUNT);
|
||||
goto err;
|
||||
}
|
||||
if (conn->last_query_type == QUERY_SELECT) {
|
||||
MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC);
|
||||
result->m.free_result(result, TRUE TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PACKET_FREE_ALLOCA(greet_packet);
|
||||
PACKET_FREE(auth_packet);
|
||||
PACKET_FREE_ALLOCA(ok_packet);
|
||||
|
||||
DBG_RETURN(conn);
|
||||
}
|
||||
@ -812,10 +838,6 @@ err:
|
||||
conn->scheme = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* This will also close conn->net.stream if it has been opened */
|
||||
conn->m->free_contents(conn TSRMLS_CC);
|
||||
|
||||
if (self_alloced) {
|
||||
/*
|
||||
We have alloced, thus there are no references to this
|
||||
@ -823,6 +845,8 @@ err:
|
||||
*/
|
||||
conn->m->dtor(conn TSRMLS_CC);
|
||||
} else {
|
||||
/* This will also close conn->net.stream if it has been opened */
|
||||
conn->m->free_contents(conn TSRMLS_CC);
|
||||
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CONNECT_FAILURE);
|
||||
}
|
||||
DBG_RETURN(NULL);
|
||||
@ -1411,8 +1435,9 @@ mysqlnd_send_close(MYSQLND * conn TSRMLS_DC)
|
||||
switch (CONN_GET_STATE(conn)) {
|
||||
case CONN_READY:
|
||||
DBG_INF("Connection clean, sending COM_QUIT");
|
||||
ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST,
|
||||
TRUE, TRUE TSRMLS_CC);
|
||||
if (conn->net.stream) {
|
||||
ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, TRUE, TRUE TSRMLS_CC);
|
||||
}
|
||||
/* Do nothing */
|
||||
break;
|
||||
case CONN_SENDING_LOAD_DATA:
|
||||
@ -1949,10 +1974,16 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
|
||||
conn->options.flags &= ~CLIENT_LOCAL_FILES;
|
||||
}
|
||||
break;
|
||||
case MYSQL_INIT_COMMAND:
|
||||
/* when num_commands is 0, then realloc will be effectively a malloc call, internally */
|
||||
conn->options.init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1),
|
||||
conn->persistent);
|
||||
conn->options.init_commands[conn->options.num_commands] = pestrdup(value, conn->persistent);
|
||||
++conn->options.num_commands;
|
||||
break;
|
||||
#ifdef WHEN_SUPPORTED_BY_MYSQLI
|
||||
case MYSQL_OPT_COMPRESS:
|
||||
#endif
|
||||
case MYSQL_INIT_COMMAND:
|
||||
case MYSQL_READ_DEFAULT_FILE:
|
||||
case MYSQL_READ_DEFAULT_GROUP:
|
||||
#ifdef WHEN_SUPPORTED_BY_MYSQLI
|
||||
@ -2161,6 +2192,7 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn)
|
||||
MYSQLND_METHOD(mysqlnd_conn, set_server_option),
|
||||
MYSQLND_METHOD(mysqlnd_conn, set_client_option),
|
||||
MYSQLND_METHOD(mysqlnd_conn, free_contents),
|
||||
MYSQLND_METHOD(mysqlnd_conn, free_options),
|
||||
MYSQLND_METHOD(mysqlnd_conn, close),
|
||||
|
||||
MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor),
|
||||
|
@ -416,6 +416,8 @@ typedef enum mysqlnd_collected_stats
|
||||
STAT_BINARY_TYPE_FETCHED_SET,
|
||||
STAT_BINARY_TYPE_FETCHED_GEOMETRY,
|
||||
STAT_BINARY_TYPE_FETCHED_OTHER,
|
||||
STAT_INIT_COMMAND_EXECUTED_COUNT,
|
||||
STAT_INIT_COMMAND_FAILED_COUNT,
|
||||
STAT_LAST /* Should be always the last */
|
||||
} enum_mysqlnd_collected_stats;
|
||||
|
||||
|
@ -151,7 +151,9 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] =
|
||||
{ STR_W_LEN("proto_binary_fetched_enum") },
|
||||
{ STR_W_LEN("proto_binary_fetched_set") },
|
||||
{ STR_W_LEN("proto_binary_fetched_geometry") },
|
||||
{ STR_W_LEN("proto_binary_fetched_other") }
|
||||
{ STR_W_LEN("proto_binary_fetched_other") },
|
||||
{ STR_W_LEN("init_command_executed_count") },
|
||||
{ STR_W_LEN("init_command_failed_count") }
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
@ -279,6 +279,7 @@ struct st_mysqlnd_conn_methods
|
||||
enum_func_status (*set_server_option)(MYSQLND * const conn, enum_mysqlnd_server_option option TSRMLS_DC);
|
||||
enum_func_status (*set_client_option)(MYSQLND * const conn, enum_mysqlnd_option option, const char * const value TSRMLS_DC);
|
||||
void (*free_contents)(MYSQLND *conn TSRMLS_DC); /* private */
|
||||
void (*free_options)(MYSQLND * conn TSRMLS_DC); /* private */
|
||||
enum_func_status (*close)(MYSQLND *conn, enum_connection_close_type close_type TSRMLS_DC);
|
||||
void (*dtor)(MYSQLND *conn TSRMLS_DC); /* private */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user