mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Remove most PG specific type subclasses
The latest version of the PG gem can actually convert the primitives for us in C code, which gives a pretty substantial speed up. A few cases were only there to add the `infinity` method, which I just put on the range type (which is the only place it was used). Floats also needed to parse `Infinity` and `NaN`, but it felt reasonable enough to put that on the generic form.
This commit is contained in:
parent
9a656a7776
commit
aafee233fb
14 changed files with 60 additions and 91 deletions
2
Gemfile
2
Gemfile
|
@ -85,7 +85,7 @@ platforms :ruby do
|
|||
gem 'sqlite3', '~> 1.3.6'
|
||||
|
||||
group :db do
|
||||
gem 'pg', '>= 0.15.0'
|
||||
gem 'pg', '>= 0.18.0'
|
||||
gem 'mysql', '>= 2.9.0'
|
||||
gem 'mysql2', '>= 0.3.13'
|
||||
end
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
require 'active_record/connection_adapters/postgresql/oid/infinity'
|
||||
|
||||
require 'active_record/connection_adapters/postgresql/oid/array'
|
||||
require 'active_record/connection_adapters/postgresql/oid/bit'
|
||||
require 'active_record/connection_adapters/postgresql/oid/bit_varying'
|
||||
require 'active_record/connection_adapters/postgresql/oid/bytea'
|
||||
require 'active_record/connection_adapters/postgresql/oid/cidr'
|
||||
require 'active_record/connection_adapters/postgresql/oid/date'
|
||||
require 'active_record/connection_adapters/postgresql/oid/date_time'
|
||||
require 'active_record/connection_adapters/postgresql/oid/decimal'
|
||||
require 'active_record/connection_adapters/postgresql/oid/enum'
|
||||
require 'active_record/connection_adapters/postgresql/oid/float'
|
||||
require 'active_record/connection_adapters/postgresql/oid/hstore'
|
||||
require 'active_record/connection_adapters/postgresql/oid/inet'
|
||||
require 'active_record/connection_adapters/postgresql/oid/integer'
|
||||
require 'active_record/connection_adapters/postgresql/oid/json'
|
||||
require 'active_record/connection_adapters/postgresql/oid/jsonb'
|
||||
require 'active_record/connection_adapters/postgresql/oid/money'
|
||||
require 'active_record/connection_adapters/postgresql/oid/point'
|
||||
require 'active_record/connection_adapters/postgresql/oid/range'
|
||||
require 'active_record/connection_adapters/postgresql/oid/specialized_string'
|
||||
require 'active_record/connection_adapters/postgresql/oid/time'
|
||||
require 'active_record/connection_adapters/postgresql/oid/uuid'
|
||||
require 'active_record/connection_adapters/postgresql/oid/vector'
|
||||
require 'active_record/connection_adapters/postgresql/oid/xml'
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class Date < Type::Date # :nodoc:
|
||||
include Infinity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,8 +3,6 @@ module ActiveRecord
|
|||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class DateTime < Type::DateTime # :nodoc:
|
||||
include Infinity
|
||||
|
||||
def cast_value(value)
|
||||
if value.is_a?(::String)
|
||||
case value
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class Float < Type::Float # :nodoc:
|
||||
include Infinity
|
||||
|
||||
def cast_value(value)
|
||||
case value
|
||||
when ::Float then value
|
||||
when 'Infinity' then ::Float::INFINITY
|
||||
when '-Infinity' then -::Float::INFINITY
|
||||
when 'NaN' then ::Float::NAN
|
||||
else value.to_f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
module Infinity # :nodoc:
|
||||
def infinity(options = {})
|
||||
options[:negative] ? -::Float::INFINITY : ::Float::INFINITY
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class Integer < Type::Integer # :nodoc:
|
||||
include Infinity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,8 +3,6 @@ module ActiveRecord
|
|||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class Money < Type::Decimal # :nodoc:
|
||||
include Infinity
|
||||
|
||||
class_attribute :precision
|
||||
|
||||
def type
|
||||
|
|
|
@ -59,13 +59,23 @@ module ActiveRecord
|
|||
def extract_bounds(value)
|
||||
from, to = value[1..-2].split(',')
|
||||
{
|
||||
from: (value[1] == ',' || from == '-infinity') ? @subtype.infinity(negative: true) : from,
|
||||
to: (value[-2] == ',' || to == 'infinity') ? @subtype.infinity : to,
|
||||
from: (value[1] == ',' || from == '-infinity') ? infinity(negative: true) : from,
|
||||
to: (value[-2] == ',' || to == 'infinity') ? infinity : to,
|
||||
exclude_start: (value[0] == '('),
|
||||
exclude_end: (value[-1] == ')')
|
||||
}
|
||||
end
|
||||
|
||||
def infinity(negative: false)
|
||||
if subtype.respond_to?(:infinity)
|
||||
subtype.infinity(negative: negative)
|
||||
elsif negative
|
||||
-::Float::INFINITY
|
||||
else
|
||||
::Float::INFINITY
|
||||
end
|
||||
end
|
||||
|
||||
def infinity?(value)
|
||||
value.respond_to?(:infinite?) && value.infinite?
|
||||
end
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module PostgreSQL
|
||||
module OID # :nodoc:
|
||||
class Time < Type::Time # :nodoc:
|
||||
include Infinity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,8 +8,9 @@ module ActiveRecord
|
|||
# - Type is an OID::Type object.
|
||||
# This class has side effects on the +store+ passed during initialization.
|
||||
class TypeMapInitializer # :nodoc:
|
||||
def initialize(store)
|
||||
def initialize(store, run_complex_types = true)
|
||||
@store = store
|
||||
@run_complex_types = run_complex_types
|
||||
end
|
||||
|
||||
def run(records)
|
||||
|
|
|
@ -127,18 +127,15 @@ module ActiveRecord
|
|||
bit_varying: OID::BitVarying,
|
||||
binary: OID::Bytea,
|
||||
cidr: OID::Cidr,
|
||||
date: OID::Date,
|
||||
date_time: OID::DateTime,
|
||||
decimal: OID::Decimal,
|
||||
enum: OID::Enum,
|
||||
float: OID::Float,
|
||||
hstore: OID::Hstore,
|
||||
inet: OID::Inet,
|
||||
json: OID::Json,
|
||||
jsonb: OID::Jsonb,
|
||||
money: OID::Money,
|
||||
point: OID::Point,
|
||||
time: OID::Time,
|
||||
uuid: OID::Uuid,
|
||||
vector: OID::Vector,
|
||||
xml: OID::Xml,
|
||||
|
|
|
@ -255,6 +255,8 @@ module ActiveRecord
|
|||
@table_alias_length = nil
|
||||
|
||||
connect
|
||||
add_pg_decoders
|
||||
|
||||
@statements = StatementPool.new @connection,
|
||||
self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
|
||||
|
||||
|
@ -459,11 +461,11 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def initialize_type_map(m) # :nodoc:
|
||||
register_class_with_limit m, 'int2', OID::Integer
|
||||
register_class_with_limit m, 'int4', OID::Integer
|
||||
register_class_with_limit m, 'int8', OID::Integer
|
||||
register_class_with_limit m, 'int2', Type::Integer
|
||||
register_class_with_limit m, 'int4', Type::Integer
|
||||
register_class_with_limit m, 'int8', Type::Integer
|
||||
m.alias_type 'oid', 'int2'
|
||||
m.register_type 'float4', OID::Float.new
|
||||
m.register_type 'float4', Type::Float.new
|
||||
m.alias_type 'float8', 'float4'
|
||||
m.register_type 'text', Type::Text.new
|
||||
register_class_with_limit m, 'varchar', Type::String
|
||||
|
@ -474,8 +476,8 @@ module ActiveRecord
|
|||
register_class_with_limit m, 'bit', OID::Bit
|
||||
register_class_with_limit m, 'varbit', OID::BitVarying
|
||||
m.alias_type 'timestamptz', 'timestamp'
|
||||
m.register_type 'date', OID::Date.new
|
||||
m.register_type 'time', OID::Time.new
|
||||
m.register_type 'date', Type::Date.new
|
||||
m.register_type 'time', Type::Time.new
|
||||
|
||||
m.register_type 'money', OID::Money.new
|
||||
m.register_type 'bytea', OID::Bytea.new
|
||||
|
@ -780,6 +782,36 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_pg_decoders
|
||||
coders_by_name = {
|
||||
'int2' => PG::TextDecoder::Integer,
|
||||
'int4' => PG::TextDecoder::Integer,
|
||||
'int8' => PG::TextDecoder::Integer,
|
||||
'oid' => PG::TextDecoder::Integer,
|
||||
'float4' => PG::TextDecoder::Float,
|
||||
'float8' => PG::TextDecoder::Float,
|
||||
'bool' => PG::TextDecoder::Boolean,
|
||||
}
|
||||
query = <<-SQL
|
||||
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
||||
FROM pg_type as t
|
||||
SQL
|
||||
coders = execute_and_clear(query, "SCHEMA", []) do |result|
|
||||
result
|
||||
.map { |row| construct_coder(row, coders_by_name['typname']) }
|
||||
.compact
|
||||
end
|
||||
|
||||
map = PG::TypeMapByOid.new
|
||||
coders.each { |coder| map.add_coder(coder) }
|
||||
@connection.type_map_for_results = map
|
||||
end
|
||||
|
||||
def construct_coder(row, coder_class)
|
||||
return unless coder_class
|
||||
coder_class.new(oid: row['oid'], name: row['typname'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,13 @@ module ActiveRecord
|
|||
private
|
||||
|
||||
def cast_value(value)
|
||||
value.to_f
|
||||
case value
|
||||
when ::Float then value
|
||||
when "Infinity" then ::Float::INFINITY
|
||||
when "-Infinity" then -::Float::INFINITY
|
||||
when "NaN" then ::Float::NAN
|
||||
else value.to_f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue