Skip to content

Column created as :decimal being treated as :integer on mysql with default: 0.0 #557

@PlaidShirtPat

Description

@PlaidShirtPat

Version information:
MYSQL DB version: 5.5.38-0ubuntu0.14.04.1
Rails version: 4.1.0
Ruby version: 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]

I created a table with the following migration:
create_table "my_table", force: true do |t|
t.decimal "my_column", default: 0.0
end

When attempting to assign values to the column, the values would be treated as integers. In the MYSQL console, the column was reported as DECIMAL(10,0) with a default of 0. In the rails console, the column was reported as type :integer and acted as one.

No idea what caused this, but setting precision: 10, scale: 2 caused rails to treat the column as a :decimal again.

Activity

sodabrew

sodabrew commented on Nov 6, 2014

@sodabrew
Collaborator

A decimal field with nothing past the decimal point sounds a lot like an integer. How do you expect this to function instead?

PlaidShirtPat

PlaidShirtPat commented on Nov 6, 2014

@PlaidShirtPat
Author

DECIMAL(10,0) acts like a decimal without the addition of default.

For example, with a table
create_table "my_table", force: true do |t|
t.decimal "my_column", default: 0.0
t.decimal "my_other_column"
end

Creates two DECIMAL(10,0) columns. If you look at the column types in rails, my_column will be :integer, while my_other_column will be :decimal.
Running the following on some MyTable record:

@my_table_record.update(my_column: 1.01, my_other_column: 1.01)
@my_table_record.my_column == 1
@my_table_record.my_other_column == 1.01
@my_table_record.my_column.is_a?(Integer)
@my_table_record.my_other_column.is_a?(BigDecimal)

I'm not sure why this is, but this is the behavior I am getting

gmile

gmile commented on Nov 21, 2014

@gmile

I can confirm this issue.

  1. 0.3.11working
  2. 0.3.13 – (the one required by rails 4.1.x) not working

I'm checking using the following line:

ActiveRecord::Base.connection.exec_query('SELECT price FROM products WHERE product_id 1;')

The price column is DECIMAL(10, 2).

We're using CLUSTRIX MySQL, if that matters.

sodabrew

sodabrew commented on Nov 22, 2014

@sodabrew
Collaborator

That helped narrow down the timeframe, and turned up this commit:

commit a099e55b678cec463b479c3589cb4dcfdcc837fc
Author: Wolfgang Kölbl <wok@iki.fi>
Date:   Tue Nov 22 21:13:43 2011 +0200

    Cast MYSQL_TYPE_DECIMAL AND MYSQL_TYPE_NEWDECIMAL to integer if number of decimals is 0

    Otherwise aggregate functions like SUM will produce decimals even when summing integers

diff --git a/ext/mysql2/result.c b/ext/mysql2/result.c
index af9fc67..d827f5b 100644
--- a/ext/mysql2/result.c
+++ b/ext/mysql2/result.c
@@ -237,7 +237,9 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
           break;
         case MYSQL_TYPE_DECIMAL:    // DECIMAL or NUMERIC field
         case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up)
-          if (strtod(row[i], NULL) == 0.000000){
+          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);
           }else{
             val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
linked a pull request that will close this issue on Nov 22, 2014
gmile

gmile commented on Nov 22, 2014

@gmile

@sodabrew fixed in #563

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @sodabrew@gmile@PlaidShirtPat

      Issue actions

        Column created as :decimal being treated as :integer on mysql with default: 0.0 · Issue #557 · brianmario/mysql2