]> granicus.if.org Git - php/commitdiff
Fixed bug #49027 (mysqli_options() doesn't work when using mysqlnd)
authorAndrey Hristov <andrey@php.net>
Thu, 27 Aug 2009 13:16:39 +0000 (13:16 +0000)
committerAndrey Hristov <andrey@php.net>
Thu, 27 Aug 2009 13:16:39 +0000 (13:16 +0000)
ext/mysqli/tests/bug49027.phpt [new file with mode: 0644]
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_enum_n_def.h
ext/mysqlnd/mysqlnd_statistics.c
ext/mysqlnd/mysqlnd_structs.h

diff --git a/ext/mysqli/tests/bug49027.phpt b/ext/mysqli/tests/bug49027.phpt
new file mode 100644 (file)
index 0000000..9e5a755
--- /dev/null
@@ -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"
+}
index b46b273f892733243396c091436819c1950562e2..b9d3ce05011a2c5084f2d517dbc0b4f2872b2cc3 100644 (file)
@@ -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),
index a1a1ae0eba1d5f325a08e1ed2f295c6df4c7ea05..fec2261775db211f64e514a9d2636cd24aa02a7d 100644 (file)
@@ -425,6 +425,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;
 
index 7e6ea5506012750c5a5a2fe9816ed9bcd5f0abff..a246bdfcf630238752333861c568fefc03f48621 100644 (file)
@@ -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") }      
 };
 /* }}} */
 
index d9f9dfcdb5ad9c73b1462be0339619b97cdd93ee..ddb7b40da6a80095be49285d6a600b549aef0126 100644 (file)
@@ -281,6 +281,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 */