Skip to content

Commit

Permalink
Make Result#fields return interned strings in Ruby 3+
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Apr 2, 2021
1 parent 346b4a4 commit 10acbf5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
2 changes: 2 additions & 0 deletions ext/mysql2/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def add_ssl_defines(header)
# Missing in RBX (https://github.com/rubinius/rubinius/issues/3771)
have_func('rb_wait_for_single_fd')

have_func("rb_enc_interned_str", "ruby.h")

# borrowed from mysqlplus
# http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[
Expand Down
13 changes: 10 additions & 3 deletions ext/mysql2/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,18 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding());
rb_field = ID2SYM(rb_field);
} else {
rb_field = rb_str_new(field->name, field->name_length);
rb_enc_associate(rb_field, conn_enc);
if (default_internal_enc) {
#ifdef HAVE_RB_ENC_INTERNED_STR
rb_field = rb_enc_interned_str(field->name, field->name_length, conn_enc);
if (default_internal_enc && default_internal_enc != conn_enc) {
rb_field = rb_str_to_interned_str(rb_str_export_to_enc(rb_field, default_internal_enc));
}
#else
rb_field = rb_enc_str_new(field->name, field->name_length, conn_enc);
if (default_internal_enc && default_internal_enc != conn_enc) {
rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
}
rb_freeze(rb_field);
#endif
}
rb_ary_store(wrapper->fields, idx, rb_field);
}
Expand Down
7 changes: 7 additions & 0 deletions spec/mysql2/result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@
result = @client.query "SELECT 'a', 'b', 'c'"
expect(result.fields).to eql(%w[a b c])
end

it "should return an array of frozen strings" do
result = @client.query "SELECT 'a', 'b', 'c'"
result.fields.each do |f|
expect(f).to be_frozen
end
end
end

context "#field_types" do
Expand Down

0 comments on commit 10acbf5

Please sign in to comment.