--- /dev/null
+--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
+
/* {{{ 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;
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);
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;
}
/* 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);
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);
}
/*
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);
}
/* }}} */
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);
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);
}
/*
{
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));
}
/* }}} */
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 :(
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 :(
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);
}
/* 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);
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));
}
/* }}} */
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));
}
/* }}} */
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:
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);
}
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,
}
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;
}
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);
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);
}
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;
/* 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;
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);
}