From e2afdd0fa8742b2a0c2edd18fa18577ead0a71f1 Mon Sep 17 00:00:00 2001 From: gentlawk <gentlawk@gmail.com> Date: Fri, 21 Jun 2019 17:42:47 +0900 Subject: [PATCH 1/3] Fix zero-datetime in statement result raises ArgumentError --- ext/mysql2/result.c | 42 +++++++++++++++++++---------------- spec/mysql2/result_spec.rb | 5 +++++ spec/mysql2/statement_spec.rb | 5 +++++ 3 files changed, 33 insertions(+), 19 deletions(-) mode change 100644 => 100755 ext/mysql2/result.c mode change 100644 => 100755 spec/mysql2/result_spec.rb mode change 100644 => 100755 spec/mysql2/statement_spec.rb diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c old mode 100644 new mode 100755 index fbff98137..94dc0d1a7 --- a/ext/mysql2/result.c +++ b/ext/mysql2/result.c @@ -419,27 +419,31 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co ts = (MYSQL_TIME*)result_buffer->buffer; seconds = (ts->year*31557600ULL) + (ts->month*2592000ULL) + (ts->day*86400ULL) + (ts->hour*3600ULL) + (ts->minute*60ULL) + ts->second; - if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead - VALUE offset = INT2NUM(0); - if (args->db_timezone == intern_local) { - offset = rb_funcall(cMysql2Client, intern_local_offset, 0); - } - val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset); - if (!NIL_P(args->app_timezone)) { - if (args->app_timezone == intern_local) { + if (seconds == 0) { + val = Qnil; + } else { + if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead + VALUE offset = INT2NUM(0); + if (args->db_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); - val = rb_funcall(val, intern_new_offset, 1, offset); - } else { // utc - val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); } - } - } else { - val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); - if (!NIL_P(args->app_timezone)) { - if (args->app_timezone == intern_local) { - val = rb_funcall(val, intern_localtime, 0); - } else { // utc - val = rb_funcall(val, intern_utc, 0); + val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset); + if (!NIL_P(args->app_timezone)) { + if (args->app_timezone == intern_local) { + offset = rb_funcall(cMysql2Client, intern_local_offset, 0); + val = rb_funcall(val, intern_new_offset, 1, offset); + } else { // utc + val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); + } + } + } else { + val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); + if (!NIL_P(args->app_timezone)) { + if (args->app_timezone == intern_local) { + val = rb_funcall(val, intern_localtime, 0); + } else { // utc + val = rb_funcall(val, intern_utc, 0); + } } } } diff --git a/spec/mysql2/result_spec.rb b/spec/mysql2/result_spec.rb old mode 100644 new mode 100755 index a70b38ef0..6654088e2 --- a/spec/mysql2/result_spec.rb +++ b/spec/mysql2/result_spec.rb @@ -297,6 +297,11 @@ expect(r.first['test']).to be_an_instance_of(Time) end + it "should return nil when timestamp is 0000-00-00T00:00:00" do + r = @client.query("SELECT CAST('0000-00-00 00:00:00' AS DATETIME) as test") + expect(r.first['test']).to be_nil + end + it "should return Time for a TIMESTAMP value when within the supported range" do expect(test_result['timestamp_test']).to be_an_instance_of(Time) expect(test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00') diff --git a/spec/mysql2/statement_spec.rb b/spec/mysql2/statement_spec.rb old mode 100644 new mode 100755 index dbc185e6b..22f6853b3 --- a/spec/mysql2/statement_spec.rb +++ b/spec/mysql2/statement_spec.rb @@ -454,6 +454,11 @@ def stmt_count expect(r.first['test']).to be_an_instance_of(Time) end + it "should return nil when timestamp is 0000-00-00T00:00:00" do + r = @client.prepare("SELECT CAST('0000-00-00 00:00:00' AS DATETIME) as test").execute + expect(r.first['test']).to be_nil + end + it "should return Time for a TIMESTAMP value when within the supported range" do expect(test_result['timestamp_test']).to be_an_instance_of(Time) expect(test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00') From 7e45d3754725e3bed2b91a9084d4b15febe6304e Mon Sep 17 00:00:00 2001 From: gentlawk <gentlawk@gmail.com> Date: Fri, 6 Dec 2019 11:33:32 +0900 Subject: [PATCH 2/3] Fix unnecessary indent of if block --- ext/mysql2/result.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c index 94dc0d1a7..3e36070e7 100755 --- a/ext/mysql2/result.c +++ b/ext/mysql2/result.c @@ -421,29 +421,27 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co if (seconds == 0) { val = Qnil; - } else { - if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead - VALUE offset = INT2NUM(0); - if (args->db_timezone == intern_local) { + } else if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead + VALUE offset = INT2NUM(0); + if (args->db_timezone == intern_local) { + offset = rb_funcall(cMysql2Client, intern_local_offset, 0); + } + val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset); + if (!NIL_P(args->app_timezone)) { + if (args->app_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); + val = rb_funcall(val, intern_new_offset, 1, offset); + } else { // utc + val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); } - val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset); - if (!NIL_P(args->app_timezone)) { - if (args->app_timezone == intern_local) { - offset = rb_funcall(cMysql2Client, intern_local_offset, 0); - val = rb_funcall(val, intern_new_offset, 1, offset); - } else { // utc - val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); - } - } - } else { - val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); - if (!NIL_P(args->app_timezone)) { - if (args->app_timezone == intern_local) { - val = rb_funcall(val, intern_localtime, 0); - } else { // utc - val = rb_funcall(val, intern_utc, 0); - } + } + } else { + val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); + if (!NIL_P(args->app_timezone)) { + if (args->app_timezone == intern_local) { + val = rb_funcall(val, intern_localtime, 0); + } else { // utc + val = rb_funcall(val, intern_utc, 0); } } } From 946532d824353029aca0087a3b09bae55c3c574b Mon Sep 17 00:00:00 2001 From: gentlawk <gentlawk@gmail.com> Date: Fri, 6 Dec 2019 12:32:02 +0900 Subject: [PATCH 3/3] Fix filemode --- ext/mysql2/result.c | 0 spec/mysql2/result_spec.rb | 0 spec/mysql2/statement_spec.rb | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 ext/mysql2/result.c mode change 100755 => 100644 spec/mysql2/result_spec.rb mode change 100755 => 100644 spec/mysql2/statement_spec.rb diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c old mode 100755 new mode 100644 diff --git a/spec/mysql2/result_spec.rb b/spec/mysql2/result_spec.rb old mode 100755 new mode 100644 diff --git a/spec/mysql2/statement_spec.rb b/spec/mysql2/statement_spec.rb old mode 100755 new mode 100644