]> granicus.if.org Git - php/commitdiff
Add mysqli_error_list() that returns an array with errors. Typically only
authorAndrey Hristov <andrey@php.net>
Thu, 4 Aug 2011 09:51:26 +0000 (09:51 +0000)
committerAndrey Hristov <andrey@php.net>
Thu, 4 Aug 2011 09:51:26 +0000 (09:51 +0000)
one and just one for libmysql. mysqlnd can return generate more than one error
during its work and with mysqli_error() only the last error is being reported.
In the array returned by mysqli_error_list() / $mysqli->error_list, all errors will be found.
The list is reset when the next command is executed

23 files changed:
ext/mysqli/mysqli_fe.c
ext/mysqli/mysqli_fe.h
ext/mysqli/mysqli_nonapi.c
ext/mysqli/mysqli_prop.c
ext/mysqli/tests/057.phpt
ext/mysqli/tests/bug34810.phpt
ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt
ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt
ext/mysqli/tests/mysqli_connect.phpt
ext/mysqli/tests/mysqli_connect_oo.phpt
ext/mysqli/tests/mysqli_kill.phpt
ext/mysqli/tests/mysqli_real_connect.phpt
ext/mysqli/tests/mysqli_real_connect_pconn.phpt
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_auth.c
ext/mysqlnd/mysqlnd_loaddata.c
ext/mysqlnd/mysqlnd_priv.h
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_result_meta.c
ext/mysqlnd/mysqlnd_structs.h

index eb133b1a80d9aa1a4e60992e6f2812468461285a..a126148b29f6ef3f45b2d443769674129405e31f 100644 (file)
@@ -352,6 +352,7 @@ const zend_function_entry mysqli_functions[] = {
 #endif
        PHP_FE(mysqli_errno,                                                            arginfo_mysqli_only_link)
        PHP_FE(mysqli_error,                                                            arginfo_mysqli_only_link)
+       PHP_FE(mysqli_error_list,                                                       arginfo_mysqli_only_link)
        PHP_FE(mysqli_stmt_execute,                                                     arginfo_mysqli_only_statement)
        PHP_FALIAS(mysqli_execute, mysqli_stmt_execute,         arginfo_mysqli_only_statement)
        PHP_FE(mysqli_fetch_field,                                                      arginfo_mysqli_only_result)
@@ -424,6 +425,7 @@ const zend_function_entry mysqli_functions[] = {
        PHP_FE(mysqli_stmt_data_seek,                                           arginfo_mysqli_stmt_data_seek)
        PHP_FE(mysqli_stmt_errno,                                                       arginfo_mysqli_only_statement)
        PHP_FE(mysqli_stmt_error,                                                       arginfo_mysqli_only_statement)
+       PHP_FE(mysqli_stmt_error_list,                                          arginfo_mysqli_only_statement)
        PHP_FE(mysqli_stmt_fetch,                                                       arginfo_mysqli_only_statement)
        PHP_FE(mysqli_stmt_field_count,                                         arginfo_mysqli_only_statement)
        PHP_FE(mysqli_stmt_free_result,                                         arginfo_mysqli_only_statement)
index bf2a70ab569418748e904891f8b14faf3d85e86b..9dc78431101c9191819795f9765bb71d94e88a9f 100644 (file)
@@ -38,6 +38,7 @@ PHP_FUNCTION(mysqli_debug);
 PHP_FUNCTION(mysqli_dump_debug_info);
 PHP_FUNCTION(mysqli_errno);
 PHP_FUNCTION(mysqli_error);
+PHP_FUNCTION(mysqli_error_list);
 PHP_FUNCTION(mysqli_fetch_all);
 PHP_FUNCTION(mysqli_fetch_array);
 PHP_FUNCTION(mysqli_fetch_assoc);
@@ -111,6 +112,7 @@ PHP_FUNCTION(mysqli_stmt_close);
 PHP_FUNCTION(mysqli_stmt_data_seek);
 PHP_FUNCTION(mysqli_stmt_errno);
 PHP_FUNCTION(mysqli_stmt_error);
+PHP_FUNCTION(mysqli_stmt_error_list);
 PHP_FUNCTION(mysqli_stmt_free_result);
 PHP_FUNCTION(mysqli_stmt_get_result);
 PHP_FUNCTION(mysqli_stmt_get_warnings);
index 11c0618c49f1bb0c2938bea5480f80e3bc95375a..8dbaed2bffefdc923dea3a082daf3483c2c5ef90 100644 (file)
@@ -385,6 +385,7 @@ PHP_FUNCTION(mysqli_fetch_all)
 /* }}} */
 
 
+
 /* {{{ proto array mysqli_get_client_stats(void)
    Returns statistics about the zval cache */
 PHP_FUNCTION(mysqli_get_client_stats)
@@ -415,6 +416,93 @@ PHP_FUNCTION(mysqli_get_connection_stats)
 #endif
 /* }}} */
 
+/* {{{ proto mixed mysqli_error_list (object connection)
+   Fetches all client errors */
+PHP_FUNCTION(mysqli_error_list)
+{
+       MY_MYSQL        *mysql;
+       zval            *mysql_link;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
+               return;
+       }
+       MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+       array_init(return_value);
+#if defined(MYSQLI_USE_MYSQLND)
+       if (mysql->mysql->error_info.error_list) {
+               MYSQLND_ERROR_LIST_ELEMENT * message;
+               zend_llist_position pos;
+               for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos);
+                        message;
+                        message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos)) 
+               {
+                       zval * single_error;
+                       MAKE_STD_ZVAL(single_error);
+                       array_init(single_error);
+                       add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
+                       add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
+                       add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
+                       add_next_index_zval(return_value, single_error);
+               }
+       }
+#else
+       if (mysql_errno(mysql->mysql)) {
+               zval * single_error;
+               MAKE_STD_ZVAL(single_error);
+               array_init(single_error);
+               add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql));
+               add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1);
+               add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1);
+               add_next_index_zval(return_value, single_error);
+       }
+#endif
+}
+/* }}} */
+
+
+/* {{{ proto string mysqli_stmt_error_list(object stmt)
+*/
+PHP_FUNCTION(mysqli_stmt_error_list)
+{
+       MY_STMT *stmt;
+       zval    *mysql_stmt;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
+               return;
+       }
+       MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
+       array_init(return_value);
+#if defined(MYSQLI_USE_MYSQLND)
+       if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info.error_list) {
+               MYSQLND_ERROR_LIST_ELEMENT * message;
+               zend_llist_position pos;
+               for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos);
+                        message;
+                        message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos)) 
+               {
+                       zval * single_error;
+                       MAKE_STD_ZVAL(single_error);
+                       array_init(single_error);
+                       add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
+                       add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
+                       add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
+                       add_next_index_zval(return_value, single_error);
+               }
+       }
+#else
+       if (mysql_stmt_errno(stmt->stmt)) {
+               zval * single_error;
+               MAKE_STD_ZVAL(single_error);
+               array_init(single_error);
+               add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt));
+               add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1);
+               add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1);
+               add_next_index_zval(return_value, single_error);
+       }
+#endif
+}
+/* }}} */
+
 
 /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
    Fetch a result row as an object */
index 8a5eef2dcd564fa38e81cb0ee53877488a10317a..9e233022c068ba16fd54f427acb0846d2076f406 100644 (file)
@@ -189,6 +189,54 @@ static int link_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
 }
 /* }}} */
 
+
+/* {{{ property link_error_list_read */
+static int link_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
+{
+       MY_MYSQL *mysql;
+
+       MAKE_STD_ZVAL(*retval);
+
+       CHECK_STATUS(MYSQLI_STATUS_VALID);
+
+       mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
+
+       array_init(*retval);
+       if (mysql) {
+#if defined(MYSQLI_USE_MYSQLND)
+               if (mysql->mysql->error_info.error_list) {
+                       MYSQLND_ERROR_LIST_ELEMENT * message;
+                       zend_llist_position pos;
+                       for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos);
+                                message;
+                                message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos)) 
+                       {
+                               zval * single_error;
+                               MAKE_STD_ZVAL(single_error);
+                               array_init(single_error);
+                               add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
+                               add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
+                               add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
+                               add_next_index_zval(*retval, single_error);
+                       }
+               }
+#else
+               if (mysql_errno(mysql->mysql)) {
+                       zval * single_error;
+                       MAKE_STD_ZVAL(single_error);
+                       array_init(single_error);
+                       add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql));
+                       add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1);
+                       add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1);
+                       add_next_index_zval(*retval, single_error);
+               }
+#endif
+       }
+       return SUCCESS;
+}
+/* }}} */
+
+
 /* link properties */
 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong, "%lu")
 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED))
@@ -202,6 +250,7 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version
 MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
 MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
+
 /* result properties */
 
 /* {{{ property result_type_read */
@@ -306,6 +355,51 @@ static int stmt_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
 }
 /* }}} */
 
+/* {{{ property stmt_error_list_read */
+static int stmt_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
+{
+       MY_STMT * stmt;
+
+       MAKE_STD_ZVAL(*retval);
+       CHECK_STATUS(MYSQLI_STATUS_INITIALIZED);
+
+       stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
+       array_init(*retval);
+       if (stmt && stmt->stmt) {
+#if defined(MYSQLI_USE_MYSQLND)
+               if (stmt->stmt->data && stmt->stmt->data->error_info.error_list) {
+                       MYSQLND_ERROR_LIST_ELEMENT * message;
+                       zend_llist_position pos;
+                       for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos);
+                                message;
+                                message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos)) 
+                       {
+                               zval * single_error;
+                               MAKE_STD_ZVAL(single_error);
+                               array_init(single_error);
+                               add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
+                               add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
+                               add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
+                               add_next_index_zval(*retval, single_error);
+                       }
+               }
+#else
+               if (mysql_stmt_errno(stmt->stmt)) {
+                       zval * single_error;
+                       MAKE_STD_ZVAL(single_error);
+                       array_init(single_error);
+                       add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt));
+                       add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1);
+                       add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1);
+                       add_next_index_zval(*retval, single_error);
+               }
+#endif
+       }
+       return SUCCESS;
+}
+/* }}} */
+
+
 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
 MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu")
@@ -323,6 +417,7 @@ const mysqli_property_entry mysqli_link_property_entries[] = {
        {"connect_error",       sizeof("connect_error") - 1,    link_connect_error_read, NULL},
        {"errno",                       sizeof("errno") - 1,                    link_errno_read, NULL},
        {"error",                       sizeof("error") - 1,                    link_error_read, NULL},
+       {"error_list",          sizeof("error_list") - 1,               link_error_list_read, NULL},
        {"field_count",         sizeof("field_count") - 1,              link_field_count_read, NULL},
        {"host_info",           sizeof("host_info") - 1,                link_host_info_read, NULL},
        {"info",                        sizeof("info") - 1,                             link_info_read, NULL},
@@ -345,6 +440,7 @@ const zend_property_info mysqli_link_property_info_entries[] = {
        {ZEND_ACC_PUBLIC, "connect_error",      sizeof("connect_error") - 1,    -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "errno",                      sizeof("errno") - 1,                    -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "error",                      sizeof("error") - 1,                    -1, 0, NULL, 0, NULL},
+       {ZEND_ACC_PUBLIC, "error_list",         sizeof("error_list") - 1,               -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "field_count",        sizeof("field_count") - 1,              -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "host_info",          sizeof("host_info") - 1,                -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "info",                       sizeof("info") - 1,                             -1, 0, NULL, 0, NULL},
@@ -385,6 +481,7 @@ const mysqli_property_entry mysqli_stmt_property_entries[] = {
        {"field_count", sizeof("field_count") - 1,      stmt_field_count_read, NULL},
        {"errno",               sizeof("errno") - 1,            stmt_errno_read, NULL},
        {"error",               sizeof("error") - 1,            stmt_error_read, NULL},
+       {"error_list",  sizeof("error_list") - 1,       stmt_error_list_read, NULL},
        {"sqlstate",    sizeof("sqlstate") - 1,         stmt_sqlstate_read, NULL},
        {"id",                  sizeof("id") - 1,                       stmt_id_read, NULL},
        {NULL, 0, NULL, NULL}
@@ -399,6 +496,7 @@ const zend_property_info mysqli_stmt_property_info_entries[] = {
        {ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1,              -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "errno",              sizeof("errno") - 1,                    -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "error",              sizeof("error") - 1,                    -1, 0, NULL, 0, NULL},
+       {ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1,               -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "sqlstate",   sizeof("sqlstate") - 1,                 -1, 0, NULL, 0, NULL},
        {ZEND_ACC_PUBLIC, "id",                 sizeof("id") - 1,                               -1, 0, NULL, 0, NULL},
        {0,                                     NULL,                   0,                                                      -1, 0, NULL, 0, NULL}
index 8c8b3eeed7d8f504f7cffa314f70b27015c23287..2cb887506aa4f91ef7a5b88497ff8ee3f3bec620 100644 (file)
@@ -91,6 +91,9 @@ object(mysqli_stmt)#%d (%d) {
   int(0)
   [%u|b%"error"]=>
   %unicode|string%(0) ""
+  [%u|b%"error_list"]=>
+  array(0) {
+  }
   [%u|b%"sqlstate"]=>
   %unicode|string%(5) "00000"
   [%u|b%"id"]=>
index 35eb71753461fc7a59adfd9b276c5c3391a6894a..c6158b99137af9141b18e63e76372128704966c2 100644 (file)
@@ -77,6 +77,9 @@ object(mysqli)#%d (%d) {
   int(0)
   [%u|b%"error"]=>
   %unicode|string%(0) ""
+  [%u|b%"error_list"]=>
+  array(0) {
+  }
   [%u|b%"field_count"]=>
   int(0)
   [%u|b%"host_info"]=>
@@ -113,6 +116,8 @@ object(mysqli)#%d (%d) {
   int(0)
   [%u|b%"error"]=>
   %unicode|string%(0) ""
+  [%u|b%"error_list"]=>
+  NULL
   [%u|b%"field_count"]=>
   NULL
   [%u|b%"host_info"]=>
index a3bd92fcfc70c50a0e256c5b142a7cacf423cecd..9eff426911af48010657aae885015804f77a0d75 100644 (file)
@@ -131,6 +131,11 @@ require_once('skipifconnectfailure.inc');
                $mysqli->error, gettype($mysqli->error),
                mysqli_error($link), gettype(mysqli_error($link)));
 
+       assert(mysqli_error_list($link) === $mysqli->error_list);
+       printf("mysqli->error_list = '%s'/%s ('%s'/%s)\n",
+               $mysqli->error_list, gettype($mysqli->error_list),
+               mysqli_error_list($link), gettype(mysqli_error_list($link)));
+
        assert(mysqli_field_count($link) === $mysqli->field_count);
        printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n",
                $mysqli->field_count, gettype($mysqli->field_count),
@@ -222,6 +227,7 @@ connect_errno
 connect_error
 errno
 error
+error_list
 field_count
 host_info
 info
@@ -241,6 +247,7 @@ connect_errno
 connect_error
 errno
 error
+error_list
 field_count
 host_info
 info
@@ -258,6 +265,7 @@ mysqli->client_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
 mysqli->client_version =  '%d'/integer ('%d'/integer)
 mysqli->errno = '0'/integer ('0'/integer)
 mysqli->error = ''/%unicode|string% (''/%unicode|string%)
+mysqli->error_list = 'Array'/array ('Array'/array)
 mysqli->field_count = '0'/integer ('0'/integer)
 mysqli->insert_id = '0'/integer ('0'/integer)
 mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%)
index d0940a7561424e7c84a15dc117d29905ee39b29f..61630b0961ec36b2621febbbd6fe6a02979fdd89 100644 (file)
@@ -151,6 +151,7 @@ connect_errno = '%s'
 connect_error = ''%s'
 errno = 'NULL'
 error = 'NULL'
+error_list = 'NULL'
 field_count = 'NULL'
 host_info = 'NULL'
 info = 'NULL'
@@ -170,6 +171,7 @@ connect_errno = '%s'
 connect_error = '%s'
 errno = 'NULL'
 error = 'NULL'
+error_list = 'NULL'
 field_count = 'NULL'
 host_info = 'NULL'
 info = 'NULL'
@@ -220,6 +222,7 @@ connect_errno = '%s'
 connect_error = '%s'
 errno = 'NULL'
 error = 'NULL'
+error_list = 'NULL'
 field_count = 'NULL'
 host_info = 'NULL'
 info = 'NULL'
@@ -239,6 +242,7 @@ connect_errno = '%s'
 connect_error = '%s'
 errno = 'NULL'
 error = 'NULL'
+error_list = 'NULL'
 field_count = 'NULL'
 host_info = 'NULL'
 info = 'NULL'
index 3ce2b588f804ab4c3d55a5043228963999148d70..c7f348323e2de29b763a72884237257d0a6456b5 100644 (file)
@@ -1129,6 +1129,14 @@ isStatic: no
 isDefault: yes
 Modifiers: 256
 
+Inspecting property 'error_list'
+isPublic: yes
+isPrivate: no
+isProtected: no
+isStatic: no
+isDefault: yes
+Modifiers: 256
+
 Inspecting property 'field_count'
 isPublic: yes
 isPrivate: no
@@ -1215,6 +1223,7 @@ Default property 'connect_errno'
 Default property 'connect_error'
 Default property 'errno'
 Default property 'error'
+Default property 'error_list'
 Default property 'field_count'
 Default property 'host_info'
 Default property 'info'
index 7cbb12721275dcedd19340543000f6abd92df4ad..acf737919887ed170202fceefaf655505f7e6a99 100644 (file)
@@ -97,6 +97,9 @@ printf("stmt->errno = '%s'\n", $stmt->errno);
 assert(mysqli_stmt_error($stmt) === $stmt->error);
 printf("stmt->error = '%s'\n", $stmt->error);
 
+assert(mysqli_stmt_error_list($stmt) === $stmt->error_list);
+var_dump("stmt->error = ", $stmt->error_list);
+
 assert(mysqli_stmt_field_count($stmt) === $stmt->field_count);
 printf("stmt->field_count = '%s'\n", $stmt->field_count);
 
@@ -143,6 +146,7 @@ Class variables:
 affected_rows
 errno
 error
+error_list
 field_count
 id
 insert_id
@@ -158,6 +162,7 @@ param_count
 field_count
 errno
 error
+error_list
 sqlstate
 id
 
@@ -173,6 +178,9 @@ stmt->affected_rows = ''
 stmt->affected_rows = '1'
 stmt->errno = '0'
 stmt->error = ''
+string(14) "stmt->error = "
+array(0) {
+}
 stmt->field_count = '0'
 stmt->id = '%d'
 stmt->insert_id = '0'
index cf7c7bede87fd384c996f3169596615e6be1c2e8..e9d6ed543fa9581965ed8be9bbbbf270bb300dd5 100644 (file)
@@ -146,7 +146,7 @@ mysqli_connect()
        print "done!";
 ?>
 --EXPECTF--
-Warning: mysqli_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
+Warning: mysqli_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
 array(1) {
   [%u|b%"testing"]=>
   %unicode|string%(21) "mysqli.default_socket"
index d406e24845d134abe7727ba6209c6a7bb21342e8..af257ca6df96c262e3870b475a9e581946d39d2b 100644 (file)
@@ -144,7 +144,7 @@ new mysqli()
        print "done!";
 ?>
 --EXPECTF--
-Warning: mysqli::mysqli(): (%d/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d
+Warning: mysqli::mysqli(): (%s/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d
 ... and now Exceptions
 Access denied for user '%s'@'%s' (using password: %s)
 done!
\ No newline at end of file
index 5706adf46d4bdee2b457b6afaeaf9ab6612ebc89..bb83dd6c057667e0793434404b213e078e5ff6f9 100644 (file)
@@ -96,6 +96,18 @@ object(mysqli)#%d (%d) {
   int(2006)
   [%u|b%"error"]=>
   %unicode|string%(%d) "%s"
+  [%u|b%"error_list"]=>
+  array(1) {
+    [0]=>
+    array(3) {
+      [%u|b%"errno"]=>
+      int(2006)
+      [%u|b%"sqlstate"]=>
+      %unicode|string%(5) "%s"
+      [%u|b%"error"]=>
+      %unicode|string%(%d) "%s"
+    }
+  }
   [%u|b%"field_count"]=>
   int(0)
   [%u|b%"host_info"]=>
index 2c371328b989be00559ec68de66217ee7cf6c7e8..350c30092eb3ddfd0bc375721c333aebf1e9ba36 100644 (file)
@@ -175,7 +175,7 @@ require_once('skipifconnectfailure.inc');
        require_once("clean_table.inc");
 ?>
 --EXPECTF--
-Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
+Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
 object(mysqli)#%d (%d) {
   [%u|b%"affected_rows"]=>
   NULL
@@ -191,6 +191,8 @@ object(mysqli)#%d (%d) {
   %s
   [%u|b%"error"]=>
   %s
+  [%u|b%"error_list"]=>
+  NULL
   [%u|b%"field_count"]=>
   NULL
   [%u|b%"host_info"]=>
index 5dedd47c9615d9a29e7a9908bafb7b9cd010a76d..4cc18198c67c72323645f6f4c3c2b75d9a9b9335 100644 (file)
@@ -151,5 +151,5 @@ mysqli.max_persistent=10
        require_once("clean_table.inc");
 ?>
 --EXPECTF--
-Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
+Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
 done!
index e02fd79099b03ac8191463cbcf437ebc435f9bd8..e850862c88e2108d42b525937445df76f55bd1f5 100644 (file)
@@ -69,6 +69,21 @@ static struct st_mysqlnd_conn_methods *mysqlnd_conn_methods;
 static struct st_mysqlnd_plugin_core mysqlnd_plugin_core;
 
 
+/* {{{ mysqlnd_error_list_pdtor */
+static void
+mysqlnd_error_list_pdtor(void * pDest)
+{
+       MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
+       TSRMLS_FETCH();
+       DBG_ENTER("mysqlnd_error_list_pdtor");
+       if (element->error) {
+               mnd_pefree(element->error, TRUE);
+       }
+       DBG_VOID_RETURN;
+}
+/* }}} */
+
+
 /* {{{ mysqlnd_library_end */
 PHPAPI void mysqlnd_library_end(TSRMLS_D)
 {
@@ -178,6 +193,11 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND * conn TSRMLS_DC)
                mnd_pefree(conn->last_message, pers);
                conn->last_message = NULL;
        }
+       if (conn->error_info.error_list) {
+               zend_llist_clean(conn->error_info.error_list);
+               mnd_pefree(conn->error_info.error_list, pers);
+               conn->error_info.error_list = NULL;
+       }
        conn->charset = NULL;
        conn->greet_charset = NULL;
 
@@ -2492,6 +2512,14 @@ PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC)
                ret = NULL;
        }
 
+       ret->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
+       if (!ret->error_info.error_list) {
+               ret->m->dtor(ret TSRMLS_CC);
+               ret = NULL;
+       } else {
+               zend_llist_init(ret->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
+       }
+
        DBG_RETURN(ret);
 }
 /* }}} */
index 1bb08013c279bb45498febb255169531c55872bf..1a56e8ef0af4d89d94379c6de41e4d047d39064b 100644 (file)
@@ -137,8 +137,7 @@ mysqlnd_auth_handshake(MYSQLND * conn,
                                strlcpy(conn->error_info.sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info.sqlstate));
                                DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error);
                        }
-                       conn->error_info.error_no = auth_resp_packet->error_no;
-                       strlcpy(conn->error_info.error, auth_resp_packet->error, sizeof(conn->error_info.error));
+                       SET_CLIENT_ERROR(conn->error_info, auth_resp_packet->error_no, UNKNOWN_SQLSTATE, auth_resp_packet->error);
                }
                goto end;
        }
@@ -235,7 +234,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
        }
 
        ret = PACKET_READ(chg_user_resp, conn);
-       conn->error_info = chg_user_resp->error_info;
+       COPY_CLIENT_ERROR(conn->error_info, chg_user_resp->error_info);
 
        if (0xFE == chg_user_resp->response_code) {
                ret = FAIL;
index e7803c816906af6f4d9536fc8fdeea8ac3de12f9..db7a9e720185dcf664854e34a1bd79dec837955f 100644 (file)
@@ -181,11 +181,12 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
 
        /* init handler: allocate read buffer and open file */
        if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) {
+               char tmp_buf[sizeof(conn->error_info.error)];
+               int tmp_error_no;
                *is_warning = TRUE;
                /* error occured */
-               strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
-               conn->error_info.error_no =
-                               infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
+               tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
+               SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
                /* write empty packet to server */
                ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC);
                goto infile_error;
@@ -208,11 +209,12 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
 
        /* error during read occured */
        if (bufsize < 0) {
+               char tmp_buf[sizeof(conn->error_info.error)];
+               int tmp_error_no;
                *is_warning = TRUE;
                DBG_ERR_FMT("Bufsize < 0, warning,  %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
-               strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
-               conn->error_info.error_no =
-                               infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
+               tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
+               SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
                goto infile_error;
        }
 
index 49ec127800634a717c6e495b7fd8136d73fb004a..5bd688a2854174adbb10a2385f3ad0f7d9282caf 100644 (file)
                (error_info).error_no = 0; \
                (error_info).error[0] = '\0'; \
                strlcpy((error_info).sqlstate, "00000", sizeof((error_info).sqlstate)); \
+               if ((error_info).error_list) { \
+                       zend_llist_clean((error_info).error_list); \
+               } \
        }
 
+
 #define SET_CLIENT_ERROR(error_info, a, b, c) \
-       { \
+{ \
+       if (0 == (a)) { \
+               SET_EMPTY_ERROR((error_info)); \
+       } else { \
                (error_info).error_no = (a); \
                strlcpy((error_info).sqlstate, (b), sizeof((error_info).sqlstate)); \
                strlcpy((error_info).error, (c), sizeof((error_info).error)); \
+               if ((error_info).error_list) {\
+                       MYSQLND_ERROR_LIST_ELEMENT error_for_the_list = {0}; \
+                                                                                                                                       \
+                       error_for_the_list.error_no = (a); \
+                       strlcpy(error_for_the_list.sqlstate, (b), sizeof(error_for_the_list.sqlstate)); \
+                       error_for_the_list.error = mnd_pestrdup((c), TRUE); \
+                       if (error_for_the_list.error) { \
+                               DBG_INF_FMT("adding error [%s] to the list", error_for_the_list.error); \
+                               zend_llist_add_element((error_info).error_list, &error_for_the_list); \
+                       } \
+               } \
+       } \
+}
+
+
+#define COPY_CLIENT_ERROR(error_info_to, error_info_from) \
+       { \
+               SET_CLIENT_ERROR((error_info_to), (error_info_from).error_no, (error_info_from).sqlstate, (error_info_from).error); \
        }
 
+
 #define SET_OOM_ERROR(error_info) SET_CLIENT_ERROR((error_info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
 
 
index 0930987094dac5e053c02ff25b2996587208e674..e4688c15646d3359e927ede34295f055ce398a5d 100644 (file)
@@ -52,6 +52,22 @@ enum_func_status mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param,
 static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC);
 static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC);
 
+
+/* {{{ mysqlnd_ps_error_list_pdtor */
+static void
+mysqlnd_ps_error_list_pdtor(void * pDest)
+{
+       MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
+       TSRMLS_FETCH();
+       DBG_ENTER("mysqlnd_ps_error_list_pdtor");
+       if (element->error) {
+               mnd_pefree(element->error, TRUE);
+       }
+       DBG_VOID_RETURN;
+}
+/* }}} */
+
+
 /* {{{ mysqlnd_stmt::store_result */
 static MYSQLND_RES *
 MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
@@ -110,7 +126,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
 
                stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
        } else {
-               conn->error_info = result->stored_data->error_info;
+               COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info);
                stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
                mnd_efree(stmt->result);
                stmt->result = NULL;
@@ -177,7 +193,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC)
                        stmt->state = MYSQLND_STMT_PREPARED;
                        result->type = MYSQLND_RES_PS_BUF;
                } else {
-                       stmt->error_info = conn->error_info;
+                       COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                        stmt->state = MYSQLND_STMT_PREPARED;
                        break;
                }
@@ -300,7 +316,8 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC)
        }
 
        if (0xFF == prepare_resp->error_code) {
-               stmt->error_info = stmt->conn->error_info = prepare_resp->error_info;
+               COPY_CLIENT_ERROR(stmt->error_info, prepare_resp->error_info);
+               COPY_CLIENT_ERROR(stmt->conn->error_info, prepare_resp->error_info);
                goto done;
        }
        ret = PASS;
@@ -484,7 +501,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
 
        ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
        if (ret == FAIL) {
-               stmt->error_info = conn->error_info;
+               COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                stmt->upsert_status.affected_rows = conn->upsert_status.affected_rows;
                if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
                        /* close the statement here, the connection has been closed */
@@ -685,7 +702,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
        }
 
        if (ret == FAIL) {
-               stmt->error_info = conn->error_info;
+               COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                DBG_INF("FAIL");
                DBG_RETURN(FAIL);
        }
@@ -902,8 +919,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
                *fetched_anything = TRUE;
        } else if (ret == FAIL) {
                if (row_packet->error_info.error_no) {
-                       stmt->conn->error_info = row_packet->error_info; 
-                       stmt->error_info = row_packet->error_info; 
+                       COPY_CLIENT_ERROR(stmt->conn->error_info, row_packet->error_info);
+                       COPY_CLIENT_ERROR(stmt->error_info, row_packet->error_info);
                }
                CONN_SET_STATE(result->conn, CONN_READY);
                result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
@@ -1014,7 +1031,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
        if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf),
                                                                                          PROT_LAST /* we will handle the response packet*/,
                                                                                          FALSE, TRUE TSRMLS_CC)) {
-               stmt->error_info = stmt->conn->error_info;
+               COPY_CLIENT_ERROR(stmt->error_info, stmt->conn->error_info);
                DBG_RETURN(FAIL);
        }
 
@@ -1218,7 +1235,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC)
                        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;
+                       COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                }
                stmt->upsert_status = conn->upsert_status;
 
@@ -1337,7 +1354,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
                        ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC);
                        mnd_efree(cmd_buf);
                        if (FAIL == ret) {
-                               stmt->error_info = conn->error_info;
+                               COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                        }
                } else {
                        ret = FAIL;
@@ -2117,6 +2134,11 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC
                stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
                stmt->result = NULL;
        }
+       if (stmt->error_info.error_list) {
+               zend_llist_clean(stmt->error_info.error_list);
+               mnd_pefree(stmt->error_info.error_list, s->persistent);
+               stmt->error_info.error_list = NULL;
+       }
 
        DBG_VOID_RETURN;
 }
@@ -2174,7 +2196,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
                        FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf),
                                                                                   PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,
                                                                                   FALSE, TRUE TSRMLS_CC)) {
-                       stmt->error_info = conn->error_info;
+                       COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
                        DBG_RETURN(FAIL);
                }
        }
@@ -2375,6 +2397,11 @@ MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
                  or normal query result will close it then.
                */
                stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
+               stmt->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
+               if (!stmt->error_info.error_list) {
+                       break;
+               }
+               zend_llist_init(stmt->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_ps_error_list_pdtor, conn->persistent);
 
                DBG_RETURN(ret);
        } while (0);
index f1c633278860a78266acba6b3777e720ceb6ab04..6262793803bc41f866494cd654a4a13b60e167ac 100644 (file)
@@ -400,7 +400,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
                          This will copy the error code and the messages, as they
                          are buffers in the struct
                        */
-                       conn->error_info = rset_header->error_info;
+                       COPY_CLIENT_ERROR(conn->error_info, rset_header->error_info);
                        ret = FAIL;
                        DBG_ERR_FMT("error=%s", rset_header->error_info.error);
                        /* Return back from CONN_QUERY_SENT */
@@ -705,7 +705,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
                }
        } else if (ret == FAIL) {
                if (row_packet->error_info.error_no) {
-                       result->conn->error_info = row_packet->error_info;
+                       COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info);
                        DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
                }
                CONN_SET_STATE(result->conn, CONN_READY);
@@ -840,7 +840,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
                result->unbuf->row_count++;
        } else if (ret == FAIL) {
                if (row_packet->error_info.error_no) {
-                       result->conn->error_info = row_packet->error_info;
+                       COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info);
                        DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
                }
                CONN_SET_STATE(result->conn, CONN_READY);
@@ -1228,7 +1228,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
        }
 
        if (ret == FAIL) {
-               set->error_info = row_packet->error_info;
+               COPY_CLIENT_ERROR(set->error_info, row_packet->error_info);
        } else {
                /* Position at the first row */
                set->data_cursor = set->data;
@@ -1277,7 +1277,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
        ret = result->m.store_result_fetch_data(conn, result, result->meta, ps_protocol TSRMLS_CC);
        if (FAIL == ret) {
                if (result->stored_data) {
-                       conn->error_info = result->stored_data->error_info;
+                       COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info);
                } else {
                        SET_OOM_ERROR(conn->error_info);
                }
index fbef4daf8c68130624e4327f5f1cc6ba25bb2003..51588016a4c0265b1bce503a4cb1560249c8f26c 100644 (file)
@@ -170,7 +170,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
                        DBG_RETURN(FAIL);
                }
                if (field_packet->error_info.error_no) {
-                       conn->error_info = field_packet->error_info;
+                       COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info);
                        /* Return back from CONN_QUERY_SENT */
                        PACKET_FREE(field_packet);
                        DBG_RETURN(FAIL);
index edea2e895c105cecf593019a87179fd2eeeff1f8..94af6ced24a82666f993ec4878df4953ad17356d 100644 (file)
@@ -102,9 +102,18 @@ typedef struct st_mysqlnd_error_info
        char error[MYSQLND_ERRMSG_SIZE+1];
        char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
        unsigned int error_no;
+       zend_llist * error_list;
 } MYSQLND_ERROR_INFO;
 
 
+typedef struct st_mysqlnd_error_list_element
+{
+       char * error;
+       char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
+       unsigned int error_no;
+} MYSQLND_ERROR_LIST_ELEMENT;
+
+
 typedef struct st_mysqlnd_infile_info
 {
        php_stream      *fd;