johannes Mon Oct 27 17:21:22 2008 UTC Added files: (Branch: PHP_5_3) /php-src/ext/mysqli/tests mysqli_insert_id_variation.phpt
Modified files: /php-src/ext/mysqlnd mysqlnd.c mysqlnd_loaddata.c mysqlnd_ps.c Log: MFH: Fix #46285 (lastInsertId() returns "0" when a deferenced PDOStatement is executed)
http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd.c?r1=1.5.2.28&r2=1.5.2.29&diff_format=u Index: php-src/ext/mysqlnd/mysqlnd.c diff -u php-src/ext/mysqlnd/mysqlnd.c:1.5.2.28 php-src/ext/mysqlnd/mysqlnd.c:1.5.2.29 --- php-src/ext/mysqlnd/mysqlnd.c:1.5.2.28 Wed Oct 1 19:47:17 2008 +++ php-src/ext/mysqlnd/mysqlnd.c Mon Oct 27 17:21:22 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd.c,v 1.5.2.28 2008/10/01 19:47:17 johannes Exp $ */ +/* $Id: mysqlnd.c,v 1.5.2.29 2008/10/27 17:21:22 johannes Exp $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -268,7 +268,8 @@ /* {{{ mysqlnd_simple_command_handle_response */ enum_func_status mysqlnd_simple_command_handle_response(MYSQLND *conn, enum php_mysql_packet_type ok_packet, - zend_bool silent, enum php_mysqlnd_server_command command + zend_bool silent, enum php_mysqlnd_server_command command, + zend_bool ignore_upsert_status TSRMLS_DC) { enum_func_status ret; @@ -309,10 +310,12 @@ ok_response.message, ok_response.message_len, conn->persistent); - conn->upsert_status.warning_count = ok_response.warning_count; - conn->upsert_status.server_status = ok_response.server_status; - conn->upsert_status.affected_rows = ok_response.affected_rows; - conn->upsert_status.last_insert_id = ok_response.last_insert_id; + if (!ignore_upsert_status) { + conn->upsert_status.warning_count = ok_response.warning_count; + conn->upsert_status.server_status = ok_response.server_status; + conn->upsert_status.affected_rows = ok_response.affected_rows; + conn->upsert_status.last_insert_id = ok_response.last_insert_id; + } } } PACKET_FREE_ALLOCA(ok_response); @@ -367,7 +370,8 @@ enum_func_status mysqlnd_simple_command(MYSQLND *conn, enum php_mysqlnd_server_command command, const char * const arg, size_t arg_len, - enum php_mysql_packet_type ok_packet, zend_bool silent TSRMLS_DC) + enum php_mysql_packet_type ok_packet, zend_bool silent, + zend_bool ignore_upsert_status TSRMLS_DC) { enum_func_status ret = PASS; php_mysql_packet_command cmd_packet; @@ -390,7 +394,9 @@ } /* clean UPSERT info */ - memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); + if (!ignore_upsert_status) { + memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); + } SET_ERROR_AFF_ROWS(conn); SET_EMPTY_ERROR(conn->error_info); @@ -409,7 +415,7 @@ DBG_ERR("Server is gone"); ret = FAIL; } else if (ok_packet != PROT_LAST) { - ret = mysqlnd_simple_command_handle_response(conn, ok_packet, silent, command TSRMLS_CC); + ret = mysqlnd_simple_command_handle_response(conn, ok_packet, silent, command, ignore_upsert_status TSRMLS_CC); } /* @@ -435,7 +441,7 @@ int2store(buffer, (uint) option); ret = mysqlnd_simple_command(conn, COM_SET_OPTION, buffer, sizeof(buffer), - PROT_EOF_PACKET, FALSE TSRMLS_CC); + PROT_EOF_PACKET, FALSE, TRUE TSRMLS_CC); DBG_RETURN(ret); } /* }}} */ @@ -850,7 +856,7 @@ if (PASS != mysqlnd_simple_command(conn, COM_QUERY, query, query_len, PROT_LAST /* we will handle the OK packet*/, - FALSE TSRMLS_CC)) { + FALSE, FALSE TSRMLS_CC)) { DBG_RETURN(FAIL); } CONN_SET_STATE(conn, CONN_QUERY_SENT); @@ -897,7 +903,7 @@ if (PASS != mysqlnd_simple_command(conn, COM_FIELD_LIST, buff, p - buff, PROT_LAST /* we will handle the OK packet*/, - FALSE TSRMLS_CC)) { + FALSE, TRUE TSRMLS_CC)) { DBG_RETURN(NULL); } /* @@ -1018,7 +1024,7 @@ { DBG_ENTER("mysqlnd_conn::dump_debug_info"); DBG_INF_FMT("conn=%llu", conn->thread_id); - DBG_RETURN(mysqlnd_simple_command(conn, COM_DEBUG, NULL, 0, PROT_EOF_PACKET, FALSE TSRMLS_CC)); + DBG_RETURN(mysqlnd_simple_command(conn, COM_DEBUG, NULL, 0, PROT_EOF_PACKET, FALSE, TRUE TSRMLS_CC)); } /* }}} */ @@ -1034,7 +1040,7 @@ DBG_ENTER("mysqlnd_conn::select_db"); DBG_INF_FMT("conn=%llu db=%s", conn->thread_id, db); - ret = mysqlnd_simple_command(conn, COM_INIT_DB, db, db_len, PROT_OK_PACKET, FALSE TSRMLS_CC); + ret = mysqlnd_simple_command(conn, COM_INIT_DB, db, db_len, PROT_OK_PACKET, FALSE, TRUE TSRMLS_CC); /* The server sends 0 but libmysql doesn't read it and has established a protocol of giving back -1. Thus we have to follow it :( @@ -1055,7 +1061,7 @@ DBG_ENTER("mysqlnd_conn::ping"); DBG_INF_FMT("conn=%llu", conn->thread_id); - ret = mysqlnd_simple_command(conn, COM_PING, NULL, 0, PROT_OK_PACKET, TRUE TSRMLS_CC); + ret = mysqlnd_simple_command(conn, COM_PING, NULL, 0, PROT_OK_PACKET, TRUE, TRUE TSRMLS_CC); /* The server sends 0 but libmysql doesn't read it and has established a protocol of giving back -1. Thus we have to follow it :( @@ -1078,7 +1084,7 @@ DBG_ENTER("mysqlnd_conn::stat"); DBG_INF_FMT("conn=%llu", conn->thread_id); - ret = mysqlnd_simple_command(conn, COM_STATISTICS, NULL, 0, PROT_LAST, FALSE TSRMLS_CC); + ret = mysqlnd_simple_command(conn, COM_STATISTICS, NULL, 0, PROT_LAST, FALSE, TRUE TSRMLS_CC); if (FAIL == ret) { DBG_RETURN(FAIL); } @@ -1112,14 +1118,14 @@ /* If we kill ourselves don't expect OK packet, PROT_LAST will skip it */ if (pid != conn->thread_id) { - ret = mysqlnd_simple_command(conn, COM_PROCESS_KILL, buff, 4, PROT_OK_PACKET, FALSE TSRMLS_CC); + ret = mysqlnd_simple_command(conn, COM_PROCESS_KILL, buff, 4, PROT_OK_PACKET, FALSE, TRUE TSRMLS_CC); /* The server sends 0 but libmysql doesn't read it and has established a protocol of giving back -1. Thus we have to follow it :( */ SET_ERROR_AFF_ROWS(conn); } else if (PASS == (ret = mysqlnd_simple_command(conn, COM_PROCESS_KILL, buff, - 4, PROT_LAST, FALSE TSRMLS_CC))) { + 4, PROT_LAST, FALSE, TRUE TSRMLS_CC))) { CONN_SET_STATE(conn, CONN_QUIT_SENT); } DBG_RETURN(ret); @@ -1172,7 +1178,7 @@ int1store(bits, options); - DBG_RETURN(mysqlnd_simple_command(conn, COM_REFRESH, (char *)bits, 1, PROT_OK_PACKET, FALSE TSRMLS_CC)); + DBG_RETURN(mysqlnd_simple_command(conn, COM_REFRESH, (char *)bits, 1, PROT_OK_PACKET, FALSE, TRUE TSRMLS_CC)); } /* }}} */ @@ -1187,7 +1193,7 @@ int1store(bits, level); - DBG_RETURN(mysqlnd_simple_command(conn, COM_SHUTDOWN, (char *)bits, 1, PROT_OK_PACKET, FALSE TSRMLS_CC)); + DBG_RETURN(mysqlnd_simple_command(conn, COM_SHUTDOWN, (char *)bits, 1, PROT_OK_PACKET, FALSE, TRUE TSRMLS_CC)); } /* }}} */ @@ -1206,7 +1212,7 @@ case CONN_READY: DBG_INF("Connection clean, sending COM_QUIT"); ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, - TRUE TSRMLS_CC); + TRUE, TRUE TSRMLS_CC); /* Do nothing */ break; case CONN_SENDING_LOAD_DATA: @@ -1633,7 +1639,7 @@ if (PASS != mysqlnd_simple_command(conn, COM_CHANGE_USER, buffer, p - buffer, PROT_LAST /* we will handle the OK packet*/, - FALSE TSRMLS_CC)) { + FALSE, TRUE TSRMLS_CC)) { DBG_RETURN(FAIL); } http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_loaddata.c?r1=1.2.2.6&r2=1.2.2.7&diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_loaddata.c diff -u php-src/ext/mysqlnd/mysqlnd_loaddata.c:1.2.2.6 php-src/ext/mysqlnd/mysqlnd_loaddata.c:1.2.2.7 --- php-src/ext/mysqlnd/mysqlnd_loaddata.c:1.2.2.6 Wed Apr 16 12:57:38 2008 +++ php-src/ext/mysqlnd/mysqlnd_loaddata.c Mon Oct 27 17:21:22 2008 @@ -27,7 +27,8 @@ enum_func_status mysqlnd_simple_command_handle_response(MYSQLND *conn, enum php_mysql_packet_type ok_packet, - zend_bool silent, enum php_mysqlnd_server_command command + zend_bool silent, enum php_mysqlnd_server_command command, + zend_bool ignore_upsert_status TSRMLS_DC); @@ -241,7 +242,7 @@ infile_error: /* get response from server and update upsert values */ - if (FAIL == mysqlnd_simple_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_QUERY TSRMLS_CC)) { + if (FAIL == mysqlnd_simple_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_QUERY, FALSE TSRMLS_CC)) { result = FAIL; goto infile_error; } http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_ps.c?r1=1.3.2.18&r2=1.3.2.19&diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_ps.c diff -u php-src/ext/mysqlnd/mysqlnd_ps.c:1.3.2.18 php-src/ext/mysqlnd/mysqlnd_ps.c:1.3.2.19 --- php-src/ext/mysqlnd/mysqlnd_ps.c:1.3.2.18 Sun Oct 19 12:28:43 2008 +++ php-src/ext/mysqlnd/mysqlnd_ps.c Mon Oct 27 17:21:22 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_ps.c,v 1.3.2.18 2008/10/19 12:28:43 johannes Exp $ */ +/* $Id: mysqlnd_ps.c,v 1.3.2.19 2008/10/27 17:21:22 johannes Exp $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -39,7 +39,8 @@ enum_func_status mysqlnd_simple_command(MYSQLND *conn, enum php_mysqlnd_server_command command, const char * const arg, size_t arg_len, enum php_mysql_packet_type ok_packet, - zend_bool silent TSRMLS_DC); + zend_bool silent, zend_bool ignore_upsert_status + TSRMLS_DC); /* Exported by mysqlnd_ps_codec.c */ zend_uchar* mysqlnd_stmt_execute_generate_request(MYSQLND_STMT *stmt, size_t *request_len, @@ -420,7 +421,7 @@ } if (FAIL == mysqlnd_simple_command(stmt_to_prepare->conn, COM_STMT_PREPARE, query, - query_len, PROT_LAST, FALSE TSRMLS_CC) || + query_len, PROT_LAST, FALSE, TRUE TSRMLS_CC) || FAIL == mysqlnd_stmt_read_prepare_response(stmt_to_prepare TSRMLS_CC)) { goto fail; } @@ -682,7 +683,7 @@ ret = mysqlnd_simple_command(stmt->conn, COM_STMT_EXECUTE, (char *)request, request_len, PROT_LAST /* we will handle the response packet*/, - FALSE TSRMLS_CC); + FALSE, FALSE TSRMLS_CC); if (free_request) { mnd_efree(request); @@ -990,7 +991,7 @@ if (FAIL == mysqlnd_simple_command(stmt->conn, COM_STMT_FETCH, (char *)buf, sizeof(buf), PROT_LAST /* we will handle the response packet*/, - FALSE TSRMLS_CC)) { + FALSE, TRUE TSRMLS_CC)) { stmt->error_info = stmt->conn->error_info; DBG_RETURN(FAIL); } @@ -1182,7 +1183,7 @@ if (CONN_GET_STATE(conn) == CONN_READY && FAIL == (ret = mysqlnd_simple_command(conn, COM_STMT_RESET, (char *)cmd_buf, sizeof(cmd_buf), PROT_OK_PACKET, - FALSE TSRMLS_CC))) { + FALSE, TRUE TSRMLS_CC))) { stmt->error_info = conn->error_info; } stmt->upsert_status = conn->upsert_status; @@ -1254,7 +1255,7 @@ /* COM_STMT_SEND_LONG_DATA doesn't send an OK packet*/ ret = mysqlnd_simple_command(conn, cmd, (char *)cmd_buf, packet_len, - PROT_LAST , FALSE TSRMLS_CC); + PROT_LAST , FALSE, TRUE TSRMLS_CC); mnd_efree(cmd_buf); if (FAIL == ret) { stmt->error_info = conn->error_info; @@ -2023,7 +2024,7 @@ if (CONN_GET_STATE(conn) == CONN_READY && FAIL == mysqlnd_simple_command(conn, COM_STMT_CLOSE, (char *)cmd_buf, sizeof(cmd_buf), PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/, - FALSE TSRMLS_CC)) { + FALSE, TRUE TSRMLS_CC)) { stmt->error_info = conn->error_info; DBG_RETURN(FAIL); } http://cvs.php.net/viewvc.cgi/php-src/ext/mysqli/tests/mysqli_insert_id_variation.phpt?view=markup&rev=1.1 Index: php-src/ext/mysqli/tests/mysqli_insert_id_variation.phpt +++ php-src/ext/mysqli/tests/mysqli_insert_id_variation.phpt --TEST-- Checking last_insert_id after different operations --SKIPIF-- <?php require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); ?> --FILE-- <?php include "connect.inc"; if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); $link->query("DROP TABLE IF EXISTS test_insert_id_var"); $link->query("CREATE TABLE test_insert_id_var (id INT auto_increment, PRIMARY KEY (id))"); $link->query("INSERT INTO test_insert_id_var VALUES (null)"); $i = $link->insert_id; if (!$i) { printf("[001] Got no valid insert id: %s", var_export($i, true)); die(); } $link->options(MYSQLI_OPT_LOCAL_INFILE, false); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[002] mysqli_option changes insert_id: %s", var_export($link->insert_id, true)); die(); } /* $link->dump_debug_info(); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[003] mysqli_debug_info changes insert_id: %s", var_export($link->insert_id, true)); die(); } */ $link->stat(); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[004] mysqli_stat changes insert_id: %s", var_export($link->insert_id, true)); die(); } /*$link->kill($link->thread_id); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[005] mysqli_kill changes insert_id: %s", var_export($link->insert_id, true)); die(); }*/ $link->ping(); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[006] mysqli_ping changes insert_id: %s", var_export($link->insert_id, true)); die(); } /* mysqlnd resets the IDE to 0 libmysql doesn't $link->change_user ($user, $passwd, $db); if (0 != $link->insert_id || 0 != mysqli_insert_id($link)) { printf("[007] mysqli_change_user changes insert_id: %s", var_export($link->insert_id, true)); die(); } */ $stmt = $link->prepare("SELECT 1"); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[008a] mysqli_prepare changes insert_id: %s", var_export($link->insert_id, true)); die(); } echo mysqli_error($link); if (0 != $stmt->insert_id || 0 != mysqli_stmt_insert_id($stmt)) { printf("[008b] mysqli_stmt doesn't initialise insert_id: %s", var_export($stmt->insert_id, true)); die(); } unset($stmt); if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { printf("[009] stmt free changes insert_id: %s", var_export($link->insert_id, true)); die(); } $link->query("DROP TABLE IF EXISTS test_insert_id_var"); echo "DONE"; --EXPECTF-- DONE
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php