From e32ec6379453c3e8eb606587c2caa3e341cb107a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Wed, 20 Dec 2017 11:14:12 -0800 Subject: [PATCH] Call BigDecimal(num) instead of BigDecimal.new(num) (#928) Call BigDecimal(num) instead of BigDecimal.new(num) to be ready for this deprecation in Ruby 2.6, and eliminate a deprecation warning now. Reduce the number of extern classes - while developing this change, I was chasing a NULL pointer on cBigDecimal from statement.c because I removed the class lookup from result.c, but extern meant the compiler did not flag it as an uninitialized value. --- benchmark/query_with_mysql_casting.rb | 2 +- ext/mysql2/result.c | 22 +++++++++++----------- ext/mysql2/statement.c | 11 +++++++---- ext/mysql2/statement.h | 2 -- spec/mysql2/statement_spec.rb | 4 ++-- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/benchmark/query_with_mysql_casting.rb b/benchmark/query_with_mysql_casting.rb index 7685926fa..18bff6dca 100644 --- a/benchmark/query_with_mysql_casting.rb +++ b/benchmark/query_with_mysql_casting.rb @@ -22,7 +22,7 @@ def mysql_cast(type, value) Mysql::Field::TYPE_INT24, Mysql::Field::TYPE_LONGLONG, Mysql::Field::TYPE_YEAR value.to_i when Mysql::Field::TYPE_DECIMAL, Mysql::Field::TYPE_NEWDECIMAL - BigDecimal.new(value) + BigDecimal(value) when Mysql::Field::TYPE_DOUBLE, Mysql::Field::TYPE_FLOAT value.to_f when Mysql::Field::TYPE_DATE diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c index ccb49a5b7..ea5592f95 100644 --- a/ext/mysql2/result.c +++ b/ext/mysql2/result.c @@ -64,14 +64,14 @@ typedef struct { VALUE block_given; } result_each_args; -VALUE cBigDecimal, cDateTime, cDate; -static VALUE cMysql2Result; -static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset; extern VALUE mMysql2, cMysql2Client, cMysql2Error; -static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset, intern_civil, intern_new_offset; -static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone, - sym_local, sym_utc, sym_cast_booleans, sym_cache_rows, sym_cast, sym_stream, sym_name; -static ID intern_merge; +static VALUE cMysql2Result, cDateTime, cDate; +static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset; +static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset, + intern_civil, intern_new_offset, intern_merge, intern_BigDecimal; +static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, + sym_application_timezone, sym_local, sym_utc, sym_cast_booleans, + sym_cache_rows, sym_cast, sym_stream, sym_name; /* Mark any VALUEs that are only referenced in C, so the GC won't get them. */ static void rb_mysql_result_mark(void * wrapper) { @@ -492,7 +492,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co } case MYSQL_TYPE_DECIMAL: // char[] case MYSQL_TYPE_NEWDECIMAL: // char[] - val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length))); + val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length))); break; case MYSQL_TYPE_STRING: // char[] case MYSQL_TYPE_VAR_STRING: // char[] @@ -602,9 +602,9 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r if (fields[i].decimals == 0) { val = rb_cstr2inum(row[i], 10); } else if (strtod(row[i], NULL) == 0.000000){ - val = rb_funcall(cBigDecimal, intern_new, 1, opt_decimal_zero); + val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, opt_decimal_zero); }else{ - val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i])); + val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(row[i], fieldLengths[i])); } break; case MYSQL_TYPE_FLOAT: /* FLOAT field */ @@ -1017,7 +1017,6 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_ } void init_mysql2_result() { - cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal")); cDate = rb_const_get(rb_cObject, rb_intern("Date")); cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime")); @@ -1036,6 +1035,7 @@ void init_mysql2_result() { intern_local_offset = rb_intern("local_offset"); intern_civil = rb_intern("civil"); intern_new_offset = rb_intern("new_offset"); + intern_BigDecimal = rb_intern("BigDecimal"); sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys")); sym_as = ID2SYM(rb_intern("as")); diff --git a/ext/mysql2/statement.c b/ext/mysql2/statement.c index 18c603ce3..909190a8e 100644 --- a/ext/mysql2/statement.c +++ b/ext/mysql2/statement.c @@ -1,8 +1,8 @@ #include -VALUE cMysql2Statement; -extern VALUE mMysql2, cMysql2Error, cBigDecimal, cDateTime, cDate; -static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s; +extern VALUE mMysql2, cMysql2Error; +static VALUE cMysql2Statement, cBigDecimal, cDateTime, cDate; +static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s, intern_merge_bang; static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year; #ifndef HAVE_RB_BIG_CMP static ID id_cmp; @@ -564,8 +564,11 @@ static VALUE rb_mysql_stmt_close(VALUE self) { } void init_mysql2_statement() { - cMysql2Statement = rb_define_class_under(mMysql2, "Statement", rb_cObject); + cDate = rb_const_get(rb_cObject, rb_intern("Date")); + cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime")); + cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal")); + cMysql2Statement = rb_define_class_under(mMysql2, "Statement", rb_cObject); rb_define_method(cMysql2Statement, "param_count", param_count, 0); rb_define_method(cMysql2Statement, "field_count", field_count, 0); rb_define_method(cMysql2Statement, "_execute", execute, -1); diff --git a/ext/mysql2/statement.h b/ext/mysql2/statement.h index 63260aab0..e48510676 100644 --- a/ext/mysql2/statement.h +++ b/ext/mysql2/statement.h @@ -1,8 +1,6 @@ #ifndef MYSQL2_STATEMENT_H #define MYSQL2_STATEMENT_H -extern VALUE cMysql2Statement; - typedef struct { VALUE client; MYSQL_STMT *stmt; diff --git a/spec/mysql2/statement_spec.rb b/spec/mysql2/statement_spec.rb index e0fccad53..38f7f37aa 100644 --- a/spec/mysql2/statement_spec.rb +++ b/spec/mysql2/statement_spec.rb @@ -178,7 +178,7 @@ def stmt_count it "should handle as a decimal binding a BigDecimal" do stmt = @client.prepare('SELECT ? AS decimal_test') - test_result = stmt.execute(BigDecimal.new("123.45")).first + test_result = stmt.execute(BigDecimal("123.45")).first expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal) expect(test_result['decimal_test']).to eql(123.45) end @@ -188,7 +188,7 @@ def stmt_count @client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test' @client.query 'CREATE TABLE mysql2_stmt_decimal_test (decimal_test DECIMAL(10,3))' - @client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal.new("123.45")) + @client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal("123.45")) test_result = @client.query("SELECT * FROM mysql2_stmt_decimal_test").first expect(test_result['decimal_test']).to eql(123.45)