Skip to content

Commit ca883e1

Browse files
authored
Make Result#fields return interned strings in Ruby 3+ (#1181)
1 parent cab9304 commit ca883e1

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

ext/mysql2/extconf.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def add_ssl_defines(header)
3131
# Missing in RBX (https://github.com/rubinius/rubinius/issues/3771)
3232
have_func('rb_wait_for_single_fd')
3333

34+
have_func("rb_enc_interned_str", "ruby.h")
35+
3436
# borrowed from mysqlplus
3537
# http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
3638
dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[

ext/mysql2/result.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,18 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo
171171
rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding());
172172
rb_field = ID2SYM(rb_field);
173173
} else {
174-
rb_field = rb_str_new(field->name, field->name_length);
175-
rb_enc_associate(rb_field, conn_enc);
176-
if (default_internal_enc) {
174+
#ifdef HAVE_RB_ENC_INTERNED_STR
175+
rb_field = rb_enc_interned_str(field->name, field->name_length, conn_enc);
176+
if (default_internal_enc && default_internal_enc != conn_enc) {
177+
rb_field = rb_str_to_interned_str(rb_str_export_to_enc(rb_field, default_internal_enc));
178+
}
179+
#else
180+
rb_field = rb_enc_str_new(field->name, field->name_length, conn_enc);
181+
if (default_internal_enc && default_internal_enc != conn_enc) {
177182
rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
178183
}
184+
rb_obj_freeze(rb_field);
185+
#endif
179186
}
180187
rb_ary_store(wrapper->fields, idx, rb_field);
181188
}

spec/mysql2/result_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@
118118
result = @client.query "SELECT 'a', 'b', 'c'"
119119
expect(result.fields).to eql(%w[a b c])
120120
end
121+
122+
it "should return an array of frozen strings" do
123+
result = @client.query "SELECT 'a', 'b', 'c'"
124+
result.fields.each do |f|
125+
expect(f).to be_frozen
126+
end
127+
end
121128
end
122129

123130
context "#field_types" do

0 commit comments

Comments
 (0)