diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index 54a7d6278..28ecd3fb5 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -17,6 +17,7 @@ VALUE cMysql2Client; extern VALUE mMysql2, cMysql2Error; static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream; +static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow; static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args; #ifndef HAVE_RB_HASH_DUP @@ -525,6 +526,8 @@ static VALUE rb_mysql_client_async_result(VALUE self) { Check_Type(current, T_HASH); resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil); + rb_mysql_set_server_query_flags(wrapper->client, resultObj); + return resultObj; } @@ -1350,6 +1353,10 @@ void init_mysql2_client() { sym_array = ID2SYM(rb_intern("array")); sym_stream = ID2SYM(rb_intern("stream")); + sym_no_good_index_used = ID2SYM(rb_intern("no_good_index_used")); + sym_no_index_used = ID2SYM(rb_intern("no_index_used")); + sym_query_was_slow = ID2SYM(rb_intern("query_was_slow")); + intern_brackets = rb_intern("[]"); intern_merge = rb_intern("merge"); intern_merge_bang = rb_intern("merge!"); @@ -1465,3 +1472,30 @@ void init_mysql2_client() { LONG2NUM(CLIENT_BASIC_FLAGS)); #endif } + +#define flag_to_bool(f) ((client->server_status & f) ? Qtrue : Qfalse) + +void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result) { + VALUE server_flags = rb_hash_new(); + +#ifdef SERVER_QUERY_NO_GOOD_INDEX_USED + rb_hash_aset(server_flags, sym_no_good_index_used, flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED)); +#else + rb_hash_aset(server_flags, sym_no_good_index_used, Qnil); +#endif + +#ifdef SERVER_QUERY_NO_INDEX_USED + rb_hash_aset(server_flags, sym_no_index_used, flag_to_bool(SERVER_QUERY_NO_INDEX_USED)); +#else + rb_hash_aset(server_flags, sym_no_index_used, Qnil); +#endif + +#ifdef SERVER_QUERY_WAS_SLOW + rb_hash_aset(server_flags, sym_query_was_slow, flag_to_bool(SERVER_QUERY_WAS_SLOW)); +#else + rb_hash_aset(server_flags, sym_query_was_slow, Qnil); +#endif + + rb_iv_set(result, "@server_flags", server_flags); +} + diff --git a/ext/mysql2/client.h b/ext/mysql2/client.h index d10274f84..47b383ec8 100644 --- a/ext/mysql2/client.h +++ b/ext/mysql2/client.h @@ -58,6 +58,7 @@ typedef struct { } void rb_mysql_client_set_active_thread(VALUE self); +void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result); #define GET_CLIENT(self) \ mysql_client_wrapper *wrapper; \ @@ -71,3 +72,4 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper); #ifndef HAVE_RB_HASH_DUP VALUE rb_hash_dup(VALUE other); #endif + diff --git a/ext/mysql2/statement.c b/ext/mysql2/statement.c index 1461e0b76..116b5de4c 100644 --- a/ext/mysql2/statement.c +++ b/ext/mysql2/statement.c @@ -379,6 +379,8 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { resultObj = rb_mysql_result_to_obj(stmt_wrapper->client, wrapper->encoding, current, metadata, self); + rb_mysql_set_server_query_flags(wrapper->client, resultObj); + if (!is_streaming) { // cache all result rb_funcall(resultObj, intern_each, 0); diff --git a/lib/mysql2/result.rb b/lib/mysql2/result.rb index e005e817c..585104e0b 100644 --- a/lib/mysql2/result.rb +++ b/lib/mysql2/result.rb @@ -1,5 +1,7 @@ module Mysql2 class Result + attr_reader :server_flags + include Enumerable end end diff --git a/spec/mysql2/result_spec.rb b/spec/mysql2/result_spec.rb index ce797baa2..196f86f6f 100644 --- a/spec/mysql2/result_spec.rb +++ b/spec/mysql2/result_spec.rb @@ -516,4 +516,20 @@ end end end + + context "server flags" do + before(:each) do + @test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1") + end + + it "should set a definitive value for query_was_slow" do + expect(@test_result.server_flags[:query_was_slow]).to eql(false) + end + it "should set a definitive value for no_index_used" do + expect(@test_result.server_flags[:no_index_used]).to eql(true) + end + it "should set a definitive value for no_good_index_used" do + expect(@test_result.server_flags[:no_good_index_used]).to eql(false) + end + end end