Skip to content

Commit 152dc92

Browse files
committed
Drop WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
And perform some code cleanups this allows.
1 parent e188d2f commit 152dc92

File tree

1 file changed

+15
-83
lines changed

1 file changed

+15
-83
lines changed

ext/mysqlnd/mysqlnd_ps.c

Lines changed: 15 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -641,39 +641,6 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, const enum_my
641641
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
642642

643643
if (stmt->result && stmt->state >= MYSQLND_STMT_PREPARED && stmt->field_count) {
644-
/*
645-
We don need to copy the data from the buffers which we will clean.
646-
Because it has already been copied. See
647-
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
648-
*/
649-
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
650-
if (stmt->result_bind &&
651-
stmt->result_zvals_separated_once == TRUE &&
652-
stmt->state >= MYSQLND_STMT_USER_FETCHING)
653-
{
654-
/*
655-
We need to copy the data from the buffers which we will clean.
656-
The bound variables point to them only if the user has started
657-
to fetch data (MYSQLND_STMT_USER_FETCHING).
658-
We need to check 'result_zvals_separated_once' or we will leak
659-
in the following scenario
660-
prepare("select 1 from dual");
661-
execute();
662-
fetch(); <-- no binding, but that's not a problem
663-
bind_result();
664-
execute(); <-- here we will leak because we separate without need
665-
*/
666-
unsigned int i;
667-
for (i = 0; i < stmt->field_count; i++) {
668-
if (stmt->result_bind[i].bound == TRUE) {
669-
zval *result = &stmt->result_bind[i].zv;
670-
ZVAL_DEREF(result);
671-
Z_TRY_ADDREF_P(result);
672-
}
673-
}
674-
}
675-
#endif
676-
677644
s->m->flush(s);
678645

679646
/*
@@ -798,28 +765,11 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, const unsign
798765

799766
ZVAL_DEREF(result);
800767
/* Clean what we copied last time */
801-
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
802768
zval_ptr_dtor(result);
803-
#endif
804769
/* copy the type */
805770
if (stmt->result_bind[i].bound == TRUE) {
806771
DBG_INF_FMT("i=%u type=%u", i, Z_TYPE(current_row[i]));
807-
if (Z_TYPE(current_row[i]) != IS_NULL) {
808-
/*
809-
Copy the value.
810-
Pre-condition is that the zvals in the result_bind buffer
811-
have been ZVAL_NULL()-ed or to another simple type
812-
(int, double, bool but not string). Because of the reference
813-
counting the user can't delete the strings the variables point to.
814-
*/
815-
816-
ZVAL_COPY_VALUE(result, &current_row[i]);
817-
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
818-
Z_TRY_ADDREF_P(result);
819-
#endif
820-
} else {
821-
ZVAL_NULL(result);
822-
}
772+
ZVAL_COPY(result, &current_row[i]);
823773
}
824774
}
825775
}
@@ -903,24 +853,15 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
903853
zval *data = &result->unbuf->last_row_data[i];
904854
zval *result = &stmt->result_bind[i].zv;
905855

856+
if (Z_TYPE_P(data) == IS_STRING && (meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))){
857+
meta->fields[i].max_length = Z_STRLEN_P(data);
858+
}
859+
906860
ZVAL_DEREF(result);
907-
/*
908-
stmt->result_bind[i].zv has been already destructed
909-
in result->unbuf->m.free_last_data()
910-
*/
911-
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
912861
zval_ptr_dtor(result);
913-
#endif
914-
if (!Z_ISNULL_P(data)) {
915-
if ((Z_TYPE_P(data) == IS_STRING) && (meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))){
916-
meta->fields[i].max_length = Z_STRLEN_P(data);
917-
}
918-
ZVAL_COPY_VALUE(result, data);
919-
/* copied data, thus also the ownership. Thus null data */
920-
ZVAL_NULL(data);
921-
} else {
922-
ZVAL_NULL(result);
923-
}
862+
ZVAL_COPY_VALUE(result, data);
863+
/* copied data, thus also the ownership. Thus null data */
864+
ZVAL_NULL(data);
924865
}
925866
}
926867
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_UNBUF);
@@ -1089,28 +1030,19 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned
10891030
zval *result = &stmt->result_bind[i].zv;
10901031

10911032
ZVAL_DEREF(result);
1092-
/*
1093-
stmt->result_bind[i].zv has been already destructed
1094-
in result->unbuf->m.free_last_data()
1095-
*/
1096-
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
10971033
zval_ptr_dtor(result);
1098-
#endif
10991034
DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, &stmt->result_bind[i].zv,
11001035
Z_TYPE_P(data), Z_REFCOUNTED(stmt->result_bind[i].zv)?
11011036
Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
11021037

1103-
if (!Z_ISNULL_P(data)) {
1104-
if ((Z_TYPE_P(data) == IS_STRING) &&
1105-
(meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))) {
1106-
meta->fields[i].max_length = Z_STRLEN_P(data);
1107-
}
1108-
ZVAL_COPY_VALUE(result, data);
1109-
/* copied data, thus also the ownership. Thus null data */
1110-
ZVAL_NULL(data);
1111-
} else {
1112-
ZVAL_NULL(result);
1038+
if (Z_TYPE_P(data) == IS_STRING &&
1039+
(meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))) {
1040+
meta->fields[i].max_length = Z_STRLEN_P(data);
11131041
}
1042+
1043+
ZVAL_COPY_VALUE(result, data);
1044+
/* copied data, thus also the ownership. Thus null data */
1045+
ZVAL_NULL(data);
11141046
}
11151047
}
11161048
} else {

0 commit comments

Comments
 (0)