diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-03 11:11:19 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-07 14:13:46 -0800 |
commit | 3efbd7fadeb3545b3b5c3df77236f4868064eabb (patch) | |
tree | f8ceb457ff5377c49c1df47d083b7264050015d6 | |
parent | 20440fd8700e1eb9725ffa0e85d458a81b519dd2 (diff) | |
download | rails-3efbd7fadeb3545b3b5c3df77236f4868064eabb.tar.gz rails-3efbd7fadeb3545b3b5c3df77236f4868064eabb.tar.bz2 rails-3efbd7fadeb3545b3b5c3df77236f4868064eabb.zip |
taking column width in to account when fetching decimal fields
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid.rb | 41 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 3 |
2 files changed, 42 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index bb2a5c0122..cf254eae8f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -116,13 +116,52 @@ module ActiveRecord end end - TYPE_MAP = {} # :nodoc: + class Decimal + def type_cast(value) + return if value.nil? + + ConnectionAdapters::Column.value_to_decimal value + end + end + + class TypeMap + def initialize + @mapping = {} + end + + def []=(oid, type) + @mapping[oid] = type + end + + def [](oid) + @mapping[oid] + end + + def fetch(ftype, fmod) + # The type for the numeric depends on the width of the field, + # so we'll do something special here. + # + # When dealing with decimal columns: + # + # places after decimal = fmod - 4 & 0xffff + # places before decimal = (fmod - 4) >> 16 & 0xffff + if ftype == 1700 && (fmod - 4 & 0xffff).zero? + ftype = 23 + end + + @mapping.fetch(ftype) { |oid| yield oid, fmod } + end + end + + TYPE_MAP = TypeMap.new # :nodoc: TYPE_MAP[23] = OID::Integer.new # int4 TYPE_MAP[20] = TYPE_MAP[23] # int8 TYPE_MAP[21] = TYPE_MAP[23] # int2 TYPE_MAP[26] = TYPE_MAP[23] # oid + TYPE_MAP[1700] = OID::Decimal.new # decimal + TYPE_MAP[25] = OID::Identity.new # text TYPE_MAP[19] = TYPE_MAP[25] # name TYPE_MAP[1043] = TYPE_MAP[25] # varchar diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 170a3ada8a..a0010ac7b7 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -712,7 +712,8 @@ module ActiveRecord types = {} result.fields.each_with_index do |fname, i| ftype = result.ftype i - types[fname] = OID::TYPE_MAP.fetch(ftype) { |oid| + fmod = result.fmod i + types[fname] = OID::TYPE_MAP.fetch(ftype, fmod) { |oid, mod| warn "unknown OID: #{fname}(#{oid}) (#{sql})" OID::Identity.new } |