Be more precise about possible types for mysqli methods

mysqli has an uncommon approach to 64-bit compatibility:
it will convert numbers that can't be represented on 32-bit
platforms to a string.
This is documented at
https://www.php.net/manual/en/mysqli-stmt.affected-rows.php#refsect1-mysqli-stmt.affected-rows-returnvalues

So if there's a query to a remote mysqli server that affects
more than 2.2 billion rows, then the opcache inference might be
incorrect.

(It's possible to add a MAY_BE_STRING_ON_32_BIT_PLATFORM bitflag macro to
account for this, but I don't think there's a need or want to?)

Patches 3162285b86

This is based on the list of php 7.4 functions using
MYSQLI_RETURN_LONG_INT in mysqli_api.c
This commit is contained in:
Tyson Andre 2019-06-09 17:37:38 -04:00 committed by Nikita Popov
parent 07c63c6fdf
commit 5d3e3a62a2
3 changed files with 9 additions and 8 deletions

View File

@ -2029,8 +2029,8 @@ PHP_FUNCTION(mysqli_stmt_send_long_data)
}
/* }}} */
/* {{{ proto mixed mysqli_stmt_affected_rows(object stmt)
Return the number of rows affected in the last query for the given link */
/* {{{ proto string|int|false mysqli_stmt_affected_rows(object stmt)
Return the number of rows affected in the last query for the given link. */
PHP_FUNCTION(mysqli_stmt_affected_rows)
{
MY_STMT *stmt;

View File

@ -90,6 +90,7 @@ PHP_MYSQLI_EXPORT(zend_object *) mysqli_objects_new(zend_class_entry *);
mysql->multi_query = 1; \
}
/* Numbers that cannot be represented as a signed int are converted to a string instead (affects 32-bit builds). */
#define MYSQLI_RETURN_LONG_INT(__val) \
{ \
if ((__val) < ZEND_LONG_MAX) { \

View File

@ -1028,7 +1028,7 @@ static const func_info_t func_infos[] = {
F1("mysqli_fetch_all", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
F1("mysqli_fetch_object", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT),
F0("mysqli_free_result", MAY_BE_NULL),
F0("mysqli_affected_rows", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_affected_rows", MAY_BE_NULL | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_autocommit", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_bind_param", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_bind_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
@ -1064,14 +1064,14 @@ static const func_info_t func_infos[] = {
F0("mysqli_get_server_version", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_info", MAY_BE_NULL | MAY_BE_STRING),
F1("mysqli_init", MAY_BE_FALSE | MAY_BE_OBJECT),
F0("mysqli_insert_id", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_insert_id", MAY_BE_NULL | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_kill", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_more_results", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_next_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_more_results", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_next_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_num_fields", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG),
F0("mysqli_num_rows", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG),
F1("mysqli_num_rows", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_options", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_ping", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F1("mysqli_prepare", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT),
@ -1080,15 +1080,15 @@ static const func_info_t func_infos[] = {
F1("mysqli_real_escape_string", MAY_BE_NULL | MAY_BE_STRING),
F0("mysqli_rollback", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_send_long_data", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_affected_rows", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_stmt_affected_rows", MAY_BE_NULL | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_stmt_close", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_data_seek", MAY_BE_NULL | MAY_BE_FALSE),
F0("mysqli_stmt_field_count", MAY_BE_NULL | MAY_BE_LONG),
F0("mysqli_stmt_free_result", MAY_BE_NULL),
F0("mysqli_stmt_insert_id", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_stmt_insert_id", MAY_BE_NULL | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_stmt_param_count", MAY_BE_NULL | MAY_BE_LONG),
F0("mysqli_stmt_reset", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F0("mysqli_stmt_num_rows", MAY_BE_NULL | MAY_BE_LONG),
F1("mysqli_stmt_num_rows", MAY_BE_NULL | MAY_BE_LONG | MAY_BE_STRING),
F0("mysqli_select_db", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
F1("mysqli_sqlstate", MAY_BE_NULL | MAY_BE_STRING),
F0("mysqli_ssl_set", MAY_BE_NULL | MAY_BE_TRUE),