Skip to content

Drop support for max_length in mysqli_fetch_fields() #6512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ PHP 8.1 UPGRADE NOTES
1. Backward Incompatible Changes
========================================

- MySQLi:
. mysqli_fetch_fields() and mysqli_fetch_field_direct() will now always return
zero for max_length. You can compute this information by iterating over the
result set and taking the maximum length. This is what PHP was doing
internally previously.

- Standard:
. version_compare() no longer accepts undocumented operator abbreviations.

Expand Down
8 changes: 2 additions & 6 deletions ext/mysqli/mysqli_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ static void php_add_field_properties(zval *value, const MYSQL_FIELD *field)
*/
add_property_string(value, "catalog", "def");

add_property_long(value, "max_length", field->max_length);
add_property_long(value, "max_length", 0);
add_property_long(value, "length", field->length);
add_property_long(value, "charsetnr", field->charsetnr);
add_property_long(value, "flags", field->flags);
Expand Down Expand Up @@ -1459,7 +1459,7 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_method)
We create always persistent, as if the user want to connect
to p:somehost, we can't convert the handle then
*/
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, TRUE)))
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, TRUE)))
#endif
{
efree(mysql);
Expand Down Expand Up @@ -2527,11 +2527,7 @@ PHP_FUNCTION(mysqli_store_result)
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifdef MYSQLI_USE_MYSQLND
result = flags & MYSQLI_STORE_RESULT_COPY_DATA? mysqlnd_store_result_ofs(mysql->mysql) : mysqlnd_store_result(mysql->mysql);
#else
result = mysql_store_result(mysql->mysql);
#endif
if (!result) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
Expand Down
11 changes: 3 additions & 8 deletions ext/mysqli/mysqli_nonapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
#ifndef MYSQLI_USE_MYSQLND
if (!(mysql->mysql = mysql_init(NULL))) {
#else
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent))) {
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, persistent))) {
#endif
goto err;
}
Expand Down Expand Up @@ -307,7 +307,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
}
}
if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
port, socket, flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA) == NULL)
port, socket, flags, MYSQLND_CLIENT_NO_FLAG) == NULL)
#endif
{
/* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
Expand Down Expand Up @@ -689,12 +689,7 @@ PHP_FUNCTION(mysqli_query)
switch (resultmode & ~MYSQLI_ASYNC) {
#endif
case MYSQLI_STORE_RESULT:
#ifdef MYSQLI_USE_MYSQLND
if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) {
result = mysqlnd_store_result_ofs(mysql->mysql);
} else
#endif
result = mysql_store_result(mysql->mysql);
result = mysql_store_result(mysql->mysql);
break;
case MYSQLI_USE_RESULT:
result = mysql_use_result(mysql->mysql);
Expand Down
2 changes: 1 addition & 1 deletion ext/mysqli/mysqli_warning.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql)
return NULL;
}

result = mysql->m->use_result(mysql, 0);
result = mysql->m->use_result(mysql);

for (;;) {
zval *entry;
Expand Down
8 changes: 2 additions & 6 deletions ext/mysqli/tests/mysqli_fetch_field.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ require_once('skipifconnectfailure.inc');
printf("[004] Expecting charset %s/%d got %d\n",
$charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
if ($tmp->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
$charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
printf("011] Expecting database '%s' got '%s'\n",
$db, $tmp->db);
Expand Down Expand Up @@ -97,7 +93,7 @@ object(stdClass)#%d (13) {
["catalog"]=>
string(%d) "%s"
["max_length"]=>
int(1)
int(0)
["length"]=>
int(11)
["charsetnr"]=>
Expand Down Expand Up @@ -159,7 +155,7 @@ object(stdClass)#%d (13) {
["catalog"]=>
string(%d) "%s"
["max_length"]=>
int(1)
int(0)
["length"]=>
int(11)
["charsetnr"]=>
Expand Down
6 changes: 1 addition & 5 deletions ext/mysqli/tests/mysqli_fetch_field_oo.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ require_once('skipifconnectfailure.inc');
printf("[005] Expecting charset %s/%d got %d\n",
$charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
if ($tmp->length != $charsetInfo->max_length) {
printf("[006] Expecting length %d got %d\n",
$charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
printf("[007] Expecting database '%s' got '%s'\n",
$db, $tmp->db);
Expand Down Expand Up @@ -86,7 +82,7 @@ object(stdClass)#%d (13) {
["catalog"]=>
string(%d) "%s"
["max_length"]=>
int(1)
int(0)
["length"]=>
int(11)
["charsetnr"]=>
Expand Down
9 changes: 2 additions & 7 deletions ext/mysqli/tests/mysqli_fetch_fields.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ require_once('skipifconnectfailure.inc');
$charsetInfo->charset,
$charsetInfo->number, $field->charsetnr);
}
if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
$charsetInfo->max_length,
$field->max_length);
}
break;
}
}
Expand Down Expand Up @@ -76,7 +71,7 @@ object(stdClass)#%d (13) {
["catalog"]=>
string(%d) "%s"
["max_length"]=>
int(1)
int(0)
["length"]=>
int(11)
["charsetnr"]=>
Expand Down Expand Up @@ -104,7 +99,7 @@ object(stdClass)#%d (13) {
["catalog"]=>
string(%d) "%s"
["max_length"]=>
int(1)
int(0)
["length"]=>
int(%d)
["charsetnr"]=>
Expand Down
6 changes: 3 additions & 3 deletions ext/mysqli/tests/mysqli_stmt_attr_set.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ require_once("connect.inc");
$res->close();
$stmt->close();

// expecting max_length to _be_ set
// MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH is no longer supported, expect no change in behavior.
$stmt = mysqli_stmt_init($link);
$stmt->prepare("SELECT label FROM test");
var_dump($stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1));
Expand All @@ -75,8 +75,8 @@ require_once("connect.inc");
$max_lengths = array();
foreach ($fields as $k => $meta) {
$max_lengths[$meta->name] = $meta->max_length;
if ($meta->max_length === 0)
printf("[008] max_length should be set (!= 0), got %s for field %s\n", $meta->max_length, $meta->name);
if ($meta->max_length !== 0)
printf("[008] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name);
}
$res->close();
$stmt->close();
Expand Down
35 changes: 16 additions & 19 deletions ext/mysqli/tests/mysqli_stmt_get_result.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ if (!function_exists('mysqli_stmt_get_result'))

mysqli_stmt_close($stmt);

// get_result cannot be used in PS cursor mode
// get_result can be used in PS cursor mode
if (!$stmt = mysqli_stmt_init($link))
printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link));

Expand All @@ -122,23 +122,10 @@ if (!function_exists('mysqli_stmt_get_result'))
if (!mysqli_stmt_execute($stmt))
printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$res = mysqli_stmt_get_result($stmt);
// we expect no segfault if we try to fetch a row because get_result should throw an error or return false
mysqli_fetch_assoc($res);
} catch (\mysqli_sql_exception $e) {
echo $e->getMessage() . "\n";
}

try {
$res = $stmt->get_result();
// we expect no segfault if we try to fetch a row because get_result should throw an error or return false
$res->fetch_assoc();
} catch (\mysqli_sql_exception $e) {
echo $e->getMessage() . "\n";
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result)) {
var_dump($row);
}
mysqli_report(MYSQLI_REPORT_OFF);

if (!$stmt = mysqli_stmt_init($link))
printf("[034] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
Expand Down Expand Up @@ -196,8 +183,18 @@ if (!function_exists('mysqli_stmt_get_result'))
mysqli_stmt object is not fully initialized
mysqli_stmt object is not fully initialized
mysqli_stmt object is not fully initialized
mysqli_stmt_get_result() cannot be used with cursors
get_result() cannot be used with cursors
array(2) {
["id"]=>
int(1)
["label"]=>
string(1) "a"
}
array(2) {
["id"]=>
int(2)
["label"]=>
string(1) "b"
}
[040] [2014] [Commands out of sync; you can't run this command now]
[041] [0] []
array(2) {
Expand Down
8 changes: 4 additions & 4 deletions ext/mysqlnd/mysqlnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ PHPAPI void mysqlnd_debug(const char *mode);
/* Query */
#define mysqlnd_fetch_into(result, flags, ret_val) (result)->m.fetch_into((result), (flags), (ret_val) ZEND_FILE_LINE_CC)
#define mysqlnd_fetch_row_c(result) (result)->m.fetch_row_c((result))
#define mysqlnd_fetch_row_zval(result, row_ptr, fetched) \
(result)->m.fetch_row((result), (row_ptr), 0, (fetched))
#define mysqlnd_fetch_all(result, flags, return_value) (result)->m.fetch_all((result), (flags), (return_value) ZEND_FILE_LINE_CC)
#define mysqlnd_get_connection_stats(conn, values) ((conn)->data)->m->get_statistics((conn)->data, (values) ZEND_FILE_LINE_CC)
#define mysqlnd_get_client_stats(values) _mysqlnd_get_client_stats(mysqlnd_global_stats, (values) ZEND_FILE_LINE_CC)
Expand All @@ -112,9 +114,8 @@ PHPAPI void mysqlnd_debug(const char *mode);

PHPAPI enum_func_status mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num);

#define mysqlnd_use_result(conn) ((conn)->data)->m->use_result((conn)->data, 0)
#define mysqlnd_store_result(conn) ((conn)->data)->m->store_result((conn)->data, MYSQLND_STORE_NO_COPY)
#define mysqlnd_store_result_ofs(conn) ((conn)->data)->m->store_result((conn)->data, MYSQLND_STORE_COPY)
#define mysqlnd_use_result(conn) ((conn)->data)->m->use_result((conn)->data)
#define mysqlnd_store_result(conn) ((conn)->data)->m->store_result((conn)->data)
#define mysqlnd_next_result(conn) ((conn)->data)->m->next_result((conn)->data)
#define mysqlnd_more_results(conn) ((conn)->data)->m->more_results((conn)->data)
#define mysqlnd_free_result(r,e_or_i) ((MYSQLND_RES*)r)->m.free_result(((MYSQLND_RES*)(r)), (e_or_i))
Expand Down Expand Up @@ -311,7 +312,6 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
zend_long debug_calloc_fail_threshold;
zend_long debug_realloc_fail_threshold;
char * sha256_server_public_key;
zend_bool fetch_data_copy;
zend_bool collect_statistics;
zend_bool collect_memory_statistics;
ZEND_END_MODULE_GLOBALS(mysqlnd)
Expand Down
29 changes: 5 additions & 24 deletions ext/mysqlnd/mysqlnd_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands)(MYSQLND_CONN_DATA * con
}
do {
if (conn->last_query_type == QUERY_SELECT) {
MYSQLND_RES * result = conn->m->use_result(conn, 0);
MYSQLND_RES * result = conn->m->use_result(conn);
if (result) {
result->m.free_result(result, TRUE);
}
Expand Down Expand Up @@ -928,7 +928,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, list_method)(MYSQLND_CONN_DATA * conn, const c
}

if (PASS == conn->m->query(conn, show_query, show_query_len)) {
result = conn->m->store_result(conn, MYSQLND_STORE_NO_COPY);
result = conn->m->store_result(conn);
}
if (show_query != query) {
mnd_sprintf_free(show_query);
Expand Down Expand Up @@ -1810,7 +1810,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons

/* {{{ mysqlnd_conn_data::use_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn, const unsigned int flags)
MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn)
{
const size_t this_func = STRUCT_OFFSET(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data), use_result);
MYSQLND_RES * result = NULL;
Expand Down Expand Up @@ -1852,7 +1852,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn, co

/* {{{ mysqlnd_conn_data::store_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn, const unsigned int flags)
MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn)
{
const size_t this_func = STRUCT_OFFSET(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data), store_result);
MYSQLND_RES * result = NULL;
Expand All @@ -1862,7 +1862,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,

if (PASS == conn->m->local_tx_start(conn, this_func)) {
do {
unsigned int f = flags;
if (!conn->current_result) {
break;
}
Expand All @@ -1875,25 +1874,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
}

MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);

/* overwrite */
if ((conn->m->get_client_api_capabilities(conn) & MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA)) {
if (MYSQLND_G(fetch_data_copy)) {
f &= ~MYSQLND_STORE_NO_COPY;
f |= MYSQLND_STORE_COPY;
}
} else {
/* if for some reason PDO borks something */
if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) {
f |= MYSQLND_STORE_COPY;
}
}
if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) {
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Unknown fetch mode");
DBG_ERR("Unknown fetch mode");
break;
}
result = conn->current_result->m.store_result(conn->current_result, conn, f);
result = conn->current_result->m.store_result(conn->current_result, conn, NULL);
if (!result) {
conn->current_result->m.free_result(conn->current_result, TRUE);
}
Expand Down
12 changes: 0 additions & 12 deletions ext/mysqlnd/mysqlnd_enum_n_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,18 +686,6 @@ enum php_mysqlnd_server_command
#define MYSQLND_REFRESH_BACKUP_LOG 0x200000L


#define MYSQLND_STORE_PS 1
#define MYSQLND_STORE_NO_COPY 2
#define MYSQLND_STORE_COPY 4

enum mysqlnd_buffered_type
{
MYSQLND_BUFFERED_TYPE_ZVAL = 1,
MYSQLND_BUFFERED_TYPE_C
};


#define MYSQLND_CLIENT_NO_FLAG 0
#define MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA 1

#endif /* MYSQLND_ENUM_N_DEF_H */
Loading