Skip to content

Commit 2d7252b

Browse files
committed
Merge pull request #341 from sodabrew/issue-243
Don't modify the connection's query_options with options set on a single query - Issue 243
2 parents fbf1695 + 3aa46fc commit 2d7252b

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

ext/mysql2/client.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
VALUE cMysql2Client;
1313
extern VALUE mMysql2, cMysql2Error;
1414
static VALUE sym_id, sym_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
15-
static ID intern_merge, intern_error_number_eql, intern_sql_state_eql;
15+
static ID intern_merge, intern_merge_bang, intern_error_number_eql, intern_sql_state_eql;
1616

1717
#ifndef HAVE_RB_HASH_DUP
1818
static VALUE rb_hash_dup(VALUE other) {
@@ -368,7 +368,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
368368
return rb_raise_mysql2_error(wrapper);
369369
}
370370

371-
VALUE is_streaming = rb_hash_aref(rb_iv_get(self, "@query_options"), sym_stream);
371+
VALUE is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
372372
if(is_streaming == Qtrue) {
373373
result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
374374
} else {
@@ -386,7 +386,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
386386

387387
resultObj = rb_mysql_result_to_obj(result);
388388
/* pass-through query options for result construction later */
389-
rb_iv_set(resultObj, "@query_options", rb_hash_dup(rb_iv_get(self, "@query_options")));
389+
rb_iv_set(resultObj, "@query_options", rb_hash_dup(rb_iv_get(self, "@current_query_options")));
390390

391391
#ifdef HAVE_RUBY_ENCODING_H
392392
GetMysql2Result(resultObj, result_wrapper);
@@ -526,7 +526,7 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
526526
#endif
527527
struct nogvl_send_query_args args;
528528
int async = 0;
529-
VALUE opts, defaults;
529+
VALUE opts, current;
530530
VALUE thread_current = rb_thread_current();
531531
#ifdef HAVE_RUBY_ENCODING_H
532532
rb_encoding *conn_enc;
@@ -536,16 +536,14 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
536536
REQUIRE_CONNECTED(wrapper);
537537
args.mysql = wrapper->client;
538538

539-
defaults = rb_iv_get(self, "@query_options");
539+
rb_iv_set(self, "@current_query_options", rb_hash_dup(rb_iv_get(self, "@query_options")));
540+
current = rb_iv_get(self, "@current_query_options");
540541
if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
541-
opts = rb_funcall(defaults, intern_merge, 1, opts);
542-
rb_iv_set(self, "@query_options", opts);
542+
opts = rb_funcall(current, intern_merge_bang, 1, opts);
543543

544-
if (rb_hash_aref(opts, sym_async) == Qtrue) {
544+
if (rb_hash_aref(current, sym_async) == Qtrue) {
545545
async = 1;
546546
}
547-
} else {
548-
opts = defaults;
549547
}
550548

551549
Check_Type(args.sql, T_STRING);
@@ -937,7 +935,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
937935

938936
resultObj = rb_mysql_result_to_obj(result);
939937
/* pass-through query options for result construction later */
940-
rb_iv_set(resultObj, "@query_options", rb_hash_dup(rb_iv_get(self, "@query_options")));
938+
rb_iv_set(resultObj, "@query_options", rb_hash_dup(rb_iv_get(self, "@current_query_options")));
941939

942940
#ifdef HAVE_RUBY_ENCODING_H
943941
GetMysql2Result(resultObj, result_wrapper);
@@ -1134,6 +1132,7 @@ void init_mysql2_client() {
11341132
sym_stream = ID2SYM(rb_intern("stream"));
11351133

11361134
intern_merge = rb_intern("merge");
1135+
intern_merge_bang = rb_intern("merge!");
11371136
intern_error_number_eql = rb_intern("error_number=");
11381137
intern_sql_state_eql = rb_intern("sql_state=");
11391138

spec/mysql2/client_spec.rb

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,26 @@ def connect *args
144144
}.should raise_error(TypeError)
145145
end
146146

147-
it "should accept an options hash that inherits from Mysql2::Client.default_query_options" do
148-
@client.query "SELECT 1", :something => :else
149-
@client.query_options.should eql(@client.query_options.merge(:something => :else))
147+
it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
148+
result = @client.query "SELECT 1", :something => :else
149+
@client.query_options[:something].should be_nil
150+
result.instance_variable_get('@query_options').should eql(@client.query_options.merge(:something => :else))
151+
@client.instance_variable_get('@current_query_options').should eql(@client.query_options.merge(:something => :else))
152+
153+
result = @client.query "SELECT 1"
154+
result.instance_variable_get('@query_options').should eql(@client.query_options)
155+
@client.instance_variable_get('@current_query_options').should eql(@client.query_options)
156+
end
157+
158+
it "should allow changing query options for subsequent queries" do
159+
@client.query_options.merge!(:something => :else)
160+
result = @client.query "SELECT 1"
161+
@client.query_options[:something].should eql(:else)
162+
result.instance_variable_get('@query_options')[:something].should eql(:else)
163+
164+
# Clean up after this test
165+
@client.query_options.delete(:something)
166+
@client.query_options[:something].should be_nil
150167
end
151168

152169
it "should return results as a hash by default" do

0 commit comments

Comments
 (0)