mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Drop support for max_length in mysqli_fetch_fields()
Retain the field, but always populate it with zero. This was already the case for PS without length updating. max_length has nothing lost in the field metadata -- it is a property of the specific result set, and requires scanning the whole result set to compute. PHP itself never uses max_length with mysqlnd, it is only exposed in the raw mysqli API. Keeping it for just that purpose is not worthwhile given the costs involved. People who actually need this for some reason can easily calculate it themselves, while making it obvious that the calculation requires a full result set scan.
This commit is contained in:
parent
95a4e1ea3b
commit
890e4caf0b
@ -19,6 +19,13 @@ 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.
|
||||
. The MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH option no longer has an effect.
|
||||
|
||||
- Standard:
|
||||
. version_compare() no longer accepts undocumented operator abbreviations.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
@ -97,7 +93,7 @@ object(stdClass)#%d (13) {
|
||||
["catalog"]=>
|
||||
string(%d) "%s"
|
||||
["max_length"]=>
|
||||
int(1)
|
||||
int(0)
|
||||
["length"]=>
|
||||
int(11)
|
||||
["charsetnr"]=>
|
||||
@ -159,7 +155,7 @@ object(stdClass)#%d (13) {
|
||||
["catalog"]=>
|
||||
string(%d) "%s"
|
||||
["max_length"]=>
|
||||
int(1)
|
||||
int(0)
|
||||
["length"]=>
|
||||
int(11)
|
||||
["charsetnr"]=>
|
||||
|
@ -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);
|
||||
@ -86,7 +82,7 @@ object(stdClass)#%d (13) {
|
||||
["catalog"]=>
|
||||
string(%d) "%s"
|
||||
["max_length"]=>
|
||||
int(1)
|
||||
int(0)
|
||||
["length"]=>
|
||||
int(11)
|
||||
["charsetnr"]=>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
@ -76,7 +71,7 @@ object(stdClass)#%d (13) {
|
||||
["catalog"]=>
|
||||
string(%d) "%s"
|
||||
["max_length"]=>
|
||||
int(1)
|
||||
int(0)
|
||||
["length"]=>
|
||||
int(11)
|
||||
["charsetnr"]=>
|
||||
@ -104,7 +99,7 @@ object(stdClass)#%d (13) {
|
||||
["catalog"]=>
|
||||
string(%d) "%s"
|
||||
["max_length"]=>
|
||||
int(1)
|
||||
int(0)
|
||||
["length"]=>
|
||||
int(%d)
|
||||
["charsetnr"]=>
|
||||
|
@ -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));
|
||||
@ -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();
|
||||
|
@ -766,22 +766,6 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, const unsign
|
||||
if (PASS != rc) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
result->stored_data->initialized_rows++;
|
||||
if (stmt->update_max_length) {
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
zend_ulong len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
@ -820,7 +804,6 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
|
||||
MYSQLND_STMT_DATA * stmt = s? s->data : NULL;
|
||||
MYSQLND_PACKET_ROW * row_packet;
|
||||
MYSQLND_CONN_DATA * conn = result->conn;
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
void *checkpoint;
|
||||
|
||||
DBG_ENTER("mysqlnd_stmt_fetch_row_unbuffered");
|
||||
@ -873,11 +856,6 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
|
||||
zval *resultzv = &stmt->result_bind[i].zv;
|
||||
if (stmt->result_bind[i].bound == TRUE) {
|
||||
zval *data = &result->unbuf->last_row_data[i];
|
||||
|
||||
if (Z_TYPE_P(data) == IS_STRING && (meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))){
|
||||
meta->fields[i].max_length = Z_STRLEN_P(data);
|
||||
}
|
||||
|
||||
ZEND_TRY_ASSIGN_VALUE_EX(resultzv, data, 0);
|
||||
/* copied data, thus also the ownership. Thus null data */
|
||||
ZVAL_NULL(data);
|
||||
@ -1026,7 +1004,6 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned
|
||||
|
||||
UPSERT_STATUS_RESET(stmt->upsert_status);
|
||||
if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
unsigned int i, field_count = result->field_count;
|
||||
|
||||
if (stmt->result_bind) {
|
||||
@ -1055,11 +1032,6 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned
|
||||
Z_TYPE_P(data), Z_REFCOUNTED(stmt->result_bind[i].zv)?
|
||||
Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
|
||||
|
||||
if (Z_TYPE_P(data) == IS_STRING &&
|
||||
(meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))) {
|
||||
meta->fields[i].max_length = Z_STRLEN_P(data);
|
||||
}
|
||||
|
||||
ZEND_TRY_ASSIGN_VALUE_EX(resultzv, data, 0);
|
||||
/* copied data, thus also the ownership. Thus null data */
|
||||
ZVAL_NULL(data);
|
||||
@ -1744,13 +1716,6 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s)
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
if (stmt->update_max_length && stmt->result->stored_data) {
|
||||
/* stored result, we have to update the max_length before we clone the meta data :( */
|
||||
stmt->result->stored_data->m.initialize_result_set_rest(stmt->result->stored_data,
|
||||
stmt->result->meta,
|
||||
conn->stats,
|
||||
conn->options->int_and_float_native);
|
||||
}
|
||||
/*
|
||||
TODO: This implementation is kind of a hack,
|
||||
find a better way to do it. In different functions I have put
|
||||
|
@ -27,115 +27,6 @@
|
||||
#include "mysqlnd_debug.h"
|
||||
#include "mysqlnd_ext_plugin.h"
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_zval::initialize_result_set_rest */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result,
|
||||
MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats,
|
||||
zend_bool int_and_float_native)
|
||||
{
|
||||
enum_func_status ret = PASS;
|
||||
const unsigned int field_count = meta->field_count;
|
||||
const uint64_t row_count = result->row_count;
|
||||
|
||||
zval *data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data;
|
||||
zval *data_cursor = data_begin;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::initialize_result_set_rest");
|
||||
|
||||
if (!data_cursor || row_count == result->initialized_rows) {
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
while ((data_cursor - data_begin) < (int)(row_count * field_count)) {
|
||||
if (Z_ISUNDEF(data_cursor[0])) {
|
||||
unsigned int i;
|
||||
const size_t current_row_num = (data_cursor - data_begin) / field_count;
|
||||
enum_func_status rc = result->m.row_decoder(&result->row_buffers[current_row_num],
|
||||
data_cursor,
|
||||
field_count,
|
||||
meta->fields,
|
||||
int_and_float_native,
|
||||
stats);
|
||||
if (rc != PASS) {
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
++result->initialized_rows;
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(data_cursor[i]) == IS_STRING) {
|
||||
const size_t len = Z_STRLEN(data_cursor[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data_cursor += field_count;
|
||||
}
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::initialize_result_set_rest */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result,
|
||||
MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats,
|
||||
const zend_bool int_and_float_native)
|
||||
{
|
||||
unsigned int row, field;
|
||||
enum_func_status ret = PASS;
|
||||
const unsigned int field_count = meta->field_count;
|
||||
const uint64_t row_count = result->row_count;
|
||||
enum_func_status rc;
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::initialize_result_set_rest");
|
||||
|
||||
if (result->initialized_rows < row_count) {
|
||||
zend_uchar *initialized = ((MYSQLND_RES_BUFFERED_C *) result)->initialized;
|
||||
zval *current_row = mnd_emalloc(field_count * sizeof(zval));
|
||||
|
||||
for (row = 0; row < result->row_count; row++) {
|
||||
/* (row / 8) & the_bit_for_row*/
|
||||
if (ZEND_BIT_TEST(initialized, row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = result->m.row_decoder(&result->row_buffers[row], current_row, field_count, meta->fields, int_and_float_native, stats);
|
||||
|
||||
if (rc != PASS) {
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
result->initialized_rows++;
|
||||
initialized[row >> 3] |= (1 << (row & 7));
|
||||
for (field = 0; field < field_count; field++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(current_row[field]) == IS_STRING) {
|
||||
const size_t len = Z_STRLEN(current_row[field]);
|
||||
if (meta->fields[field].max_length < len) {
|
||||
meta->fields[field].max_length = len;
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor_nogc(¤t_row[field]);
|
||||
}
|
||||
}
|
||||
mnd_efree(current_row);
|
||||
}
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_unbuffered::free_last_data */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_unbuffered, free_last_data)(MYSQLND_RES_UNBUFFERED * unbuf, MYSQLND_STATS * const global_stats)
|
||||
@ -219,8 +110,6 @@ static void
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, free_result)(MYSQLND_RES_BUFFERED_C * const set)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::free_result");
|
||||
mnd_efree(set->initialized);
|
||||
set->initialized = NULL;
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
@ -690,10 +579,6 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
|
||||
if (lengths) {
|
||||
lengths[i] = len;
|
||||
}
|
||||
|
||||
if (field->max_length < len) {
|
||||
field->max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
result->unbuf->row_count++;
|
||||
@ -825,10 +710,6 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
|
||||
if (lengths) {
|
||||
lengths[i] = len;
|
||||
}
|
||||
|
||||
if (field->max_length < len) {
|
||||
field->max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -944,20 +825,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
++set->initialized_rows;
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
const size_t len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* BEGIN difference between normal normal fetch and _c */
|
||||
@ -1029,20 +896,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
++set->initialized_rows;
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
const size_t len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
@ -1117,25 +970,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
if (!ZEND_BIT_TEST(set->initialized, set->current_row)) {
|
||||
set->initialized[set->current_row >> 3] |= (1 << (set->current_row & 7)); /* mark initialized */
|
||||
|
||||
++set->initialized_rows;
|
||||
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
const size_t len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; ++i) {
|
||||
zval * data = ¤t_row[i];
|
||||
@ -1393,7 +1227,6 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||
} else if (flags & MYSQLND_STORE_COPY) {
|
||||
MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result->stored_data;
|
||||
set->current_row = 0;
|
||||
set->initialized = mnd_ecalloc((unsigned int) ((set->row_count / 8) + 1), sizeof(zend_uchar)); /* +1 for safety */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1547,28 +1380,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field)(MYSQLND_RES * const result)
|
||||
DBG_ENTER("mysqlnd_res::fetch_field");
|
||||
do {
|
||||
if (result->meta) {
|
||||
/*
|
||||
We optimize the result set, so we don't convert all the data from raw buffer format to
|
||||
zval arrays during store. In the case someone doesn't read all the lines this will
|
||||
save time. However, when a metadata call is done, we need to calculate max_length.
|
||||
We don't have control whether max_length will be used, unfortunately. Otherwise we
|
||||
could have been able to skip that step.
|
||||
Well, if the mysqli API switches from returning stdClass to class like mysqli_field_metadata,
|
||||
then we can have max_length as dynamic property, which will be calculated during runtime and
|
||||
not during mysqli_fetch_field() time.
|
||||
*/
|
||||
if (result->stored_data && (result->stored_data->initialized_rows < result->stored_data->row_count)) {
|
||||
const MYSQLND_CONN_DATA * const conn = result->conn;
|
||||
DBG_INF_FMT("We have decode the whole result set to be able to satisfy this meta request");
|
||||
/* we have to initialize the rest to get the updated max length */
|
||||
if (PASS != result->stored_data->m.initialize_result_set_rest(result->stored_data,
|
||||
result->meta,
|
||||
conn->stats,
|
||||
conn->options->int_and_float_native))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_RETURN(result->meta->m->fetch_field(result->meta));
|
||||
}
|
||||
} while (0);
|
||||
@ -1584,28 +1395,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_direct)(MYSQLND_RES * const result, cons
|
||||
DBG_ENTER("mysqlnd_res::fetch_field_direct");
|
||||
do {
|
||||
if (result->meta) {
|
||||
/*
|
||||
We optimize the result set, so we don't convert all the data from raw buffer format to
|
||||
zval arrays during store. In the case someone doesn't read all the lines this will
|
||||
save time. However, when a metadata call is done, we need to calculate max_length.
|
||||
We don't have control whether max_length will be used, unfortunately. Otherwise we
|
||||
could have been able to skip that step.
|
||||
Well, if the mysqli API switches from returning stdClass to class like mysqli_field_metadata,
|
||||
then we can have max_length as dynamic property, which will be calculated during runtime and
|
||||
not during mysqli_fetch_field_direct() time.
|
||||
*/
|
||||
if (result->stored_data && (result->stored_data->initialized_rows < result->stored_data->row_count)) {
|
||||
const MYSQLND_CONN_DATA * const conn = result->conn;
|
||||
DBG_INF_FMT("We have decode the whole result set to be able to satisfy this meta request");
|
||||
/* we have to initialized the rest to get the updated max length */
|
||||
if (PASS != result->stored_data->m.initialize_result_set_rest(result->stored_data,
|
||||
result->meta,
|
||||
conn->stats,
|
||||
conn->options->int_and_float_native))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_RETURN(result->meta->m->fetch_field_direct(result->meta, fieldnr));
|
||||
}
|
||||
} while (0);
|
||||
@ -1622,17 +1411,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_fields)(MYSQLND_RES * const result)
|
||||
DBG_ENTER("mysqlnd_res::fetch_fields");
|
||||
do {
|
||||
if (result->meta) {
|
||||
if (result->stored_data && (result->stored_data->initialized_rows < result->stored_data->row_count)) {
|
||||
const MYSQLND_CONN_DATA * const conn = result->conn;
|
||||
/* we have to initialize the rest to get the updated max length */
|
||||
if (PASS != result->stored_data->m.initialize_result_set_rest(result->stored_data,
|
||||
result->meta,
|
||||
conn->stats,
|
||||
conn->options->int_and_float_native))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_RETURN(result->meta->m->fetch_fields(result->meta));
|
||||
}
|
||||
} while (0);
|
||||
@ -1799,7 +1577,6 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_result_buffered)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, num_rows),
|
||||
NULL, /* fetch_lengths */
|
||||
NULL, /* data_seek */
|
||||
NULL, /* initialize_result_set_rest */
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, free_result)
|
||||
MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
@ -1903,7 +1680,6 @@ mysqlnd_result_buffered_zval_init(MYSQLND_RES * result, const unsigned int field
|
||||
ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row);
|
||||
ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths);
|
||||
ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_zval, data_seek);
|
||||
ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
@ -1942,7 +1718,6 @@ mysqlnd_result_buffered_c_init(MYSQLND_RES * result, const unsigned int field_co
|
||||
ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row);
|
||||
ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_lengths);
|
||||
ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_c, data_seek);
|
||||
ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest);
|
||||
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
|
@ -215,9 +215,8 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field)(MYSQLND_RES_METADATA * const meta)
|
||||
DBG_INF("no more fields");
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
DBG_INF_FMT("name=%s max_length=%u",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
|
||||
meta->fields[meta->current_field].max_length);
|
||||
DBG_INF_FMT("name=%s",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"");
|
||||
DBG_RETURN(&meta->fields[meta->current_field++]);
|
||||
}
|
||||
/* }}} */
|
||||
@ -229,9 +228,8 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct)(const MYSQLND_RES_METADATA
|
||||
{
|
||||
DBG_ENTER("mysqlnd_res_meta::fetch_field_direct");
|
||||
DBG_INF_FMT("fieldnr=%u", fieldnr);
|
||||
DBG_INF_FMT("name=%s max_length=%u",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
|
||||
meta->fields[meta->current_field].max_length);
|
||||
DBG_INF_FMT("name=%s",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"");
|
||||
DBG_RETURN(&meta->fields[fieldnr]);
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -89,7 +89,6 @@ typedef struct st_mysqlnd_field
|
||||
const char *catalog; /* Catalog for table */
|
||||
char *def; /* Default value */
|
||||
zend_ulong length; /* Width of column (create length) */
|
||||
zend_ulong max_length; /* Max width for selected set */
|
||||
unsigned int name_length;
|
||||
unsigned int org_name_length;
|
||||
unsigned int table_length;
|
||||
@ -718,8 +717,6 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_unbuffered)
|
||||
};
|
||||
|
||||
typedef uint64_t (*func_mysqlnd_result_buffered__num_rows)(const MYSQLND_RES_BUFFERED * const result);
|
||||
typedef enum_func_status (*func_mysqlnd_result_buffered__initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats, const zend_bool int_and_float_native);
|
||||
typedef const size_t * (*func_mysqlnd_result_buffered__fetch_lengths)(const MYSQLND_RES_BUFFERED * const result);
|
||||
typedef enum_func_status (*func_mysqlnd_result_buffered__data_seek)(MYSQLND_RES_BUFFERED * const result, const uint64_t row);
|
||||
typedef void (*func_mysqlnd_result_buffered__free_result)(MYSQLND_RES_BUFFERED * const result);
|
||||
@ -731,7 +728,6 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_buffered)
|
||||
func_mysqlnd_result_buffered__num_rows num_rows;
|
||||
func_mysqlnd_result_buffered__fetch_lengths fetch_lengths;
|
||||
func_mysqlnd_result_buffered__data_seek data_seek;
|
||||
func_mysqlnd_result_buffered__initialize_result_set_rest initialize_result_set_rest;
|
||||
func_mysqlnd_result_buffered__free_result free_result;
|
||||
};
|
||||
|
||||
@ -1185,7 +1181,6 @@ struct st_mysqlnd_result_metadata
|
||||
#define def_mysqlnd_buffered_result_parent \
|
||||
MYSQLND_ROW_BUFFER *row_buffers; \
|
||||
uint64_t row_count; \
|
||||
uint64_t initialized_rows; \
|
||||
\
|
||||
/* Column lengths of current row - both buffered and unbuffered. For buffered results it duplicates the data found in **data */ \
|
||||
size_t *lengths; \
|
||||
@ -1224,7 +1219,6 @@ struct st_mysqlnd_buffered_result_c
|
||||
{
|
||||
def_mysqlnd_buffered_result_parent;
|
||||
|
||||
zend_uchar *initialized; /* every row is a single bit */
|
||||
uint64_t current_row;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user