Skip to content
Open
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
15 changes: 15 additions & 0 deletions ext/mysql2/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,9 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
}

if (wrapper->fields == Qnil) {
if (wrapper->resultFreed) {
rb_raise(cMysql2Error, "Result set has already been freed");
}
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
}
Expand All @@ -958,6 +961,9 @@ static VALUE rb_mysql_result_fetch_field_types(VALUE self) {
GET_RESULT(self);

if (wrapper->fieldTypes == Qnil) {
if (wrapper->resultFreed) {
rb_raise(cMysql2Error, "Result set has already been freed");
}
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
wrapper->fieldTypes = rb_ary_new2(wrapper->numberOfFields);
}
Expand Down Expand Up @@ -1192,6 +1198,7 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
wrapper->lastRowProcessed = 0;
wrapper->resultFreed = 0;
wrapper->result = r;
wrapper->numberOfFields = 0;
wrapper->fields = Qnil;
wrapper->fieldTypes = Qnil;
wrapper->rows = Qnil;
Expand Down Expand Up @@ -1221,6 +1228,14 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
* should be processed here. */
wrapper->is_streaming = (rb_hash_aref(options, sym_stream) == Qtrue ? 1 : 0);

/* Eagerly populate fields for non-streaming results to prevent
* segfault/error when accessing .fields on 0-row results that get freed
* after iteration completes but before .fields is accessed.
* See: https://github.com/brianmario/mysql2/issues/1426 */
if (r != NULL && !wrapper->is_streaming) {
rb_mysql_result_fetch_fields(obj);
}

return obj;
}

Expand Down