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'
|
gem 'sqlite3', '~> 1.3.6'
|
||||||
|
|
||||||
group :db do
|
group :db do
|
||||||
gem 'pg', '>= 0.15.0'
|
gem 'pg', '>= 0.18.0'
|
||||||
gem 'mysql', '>= 2.9.0'
|
gem 'mysql', '>= 2.9.0'
|
||||||
gem 'mysql2', '>= 0.3.13'
|
gem 'mysql2', '>= 0.3.13'
|
||||||
end
|
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/array'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/bit'
|
require 'active_record/connection_adapters/postgresql/oid/bit'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/bit_varying'
|
require 'active_record/connection_adapters/postgresql/oid/bit_varying'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/bytea'
|
require 'active_record/connection_adapters/postgresql/oid/bytea'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/cidr'
|
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/date_time'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/decimal'
|
require 'active_record/connection_adapters/postgresql/oid/decimal'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/enum'
|
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/hstore'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/inet'
|
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/json'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/jsonb'
|
require 'active_record/connection_adapters/postgresql/oid/jsonb'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/money'
|
require 'active_record/connection_adapters/postgresql/oid/money'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/point'
|
require 'active_record/connection_adapters/postgresql/oid/point'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/range'
|
require 'active_record/connection_adapters/postgresql/oid/range'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/specialized_string'
|
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/uuid'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/vector'
|
require 'active_record/connection_adapters/postgresql/oid/vector'
|
||||||
require 'active_record/connection_adapters/postgresql/oid/xml'
|
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 PostgreSQL
|
||||||
module OID # :nodoc:
|
module OID # :nodoc:
|
||||||
class DateTime < Type::DateTime # :nodoc:
|
class DateTime < Type::DateTime # :nodoc:
|
||||||
include Infinity
|
|
||||||
|
|
||||||
def cast_value(value)
|
def cast_value(value)
|
||||||
if value.is_a?(::String)
|
if value.is_a?(::String)
|
||||||
case value
|
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 PostgreSQL
|
||||||
module OID # :nodoc:
|
module OID # :nodoc:
|
||||||
class Money < Type::Decimal # :nodoc:
|
class Money < Type::Decimal # :nodoc:
|
||||||
include Infinity
|
|
||||||
|
|
||||||
class_attribute :precision
|
class_attribute :precision
|
||||||
|
|
||||||
def type
|
def type
|
||||||
|
|
|
@ -59,13 +59,23 @@ module ActiveRecord
|
||||||
def extract_bounds(value)
|
def extract_bounds(value)
|
||||||
from, to = value[1..-2].split(',')
|
from, to = value[1..-2].split(',')
|
||||||
{
|
{
|
||||||
from: (value[1] == ',' || from == '-infinity') ? @subtype.infinity(negative: true) : from,
|
from: (value[1] == ',' || from == '-infinity') ? infinity(negative: true) : from,
|
||||||
to: (value[-2] == ',' || to == 'infinity') ? @subtype.infinity : to,
|
to: (value[-2] == ',' || to == 'infinity') ? infinity : to,
|
||||||
exclude_start: (value[0] == '('),
|
exclude_start: (value[0] == '('),
|
||||||
exclude_end: (value[-1] == ')')
|
exclude_end: (value[-1] == ')')
|
||||||
}
|
}
|
||||||
end
|
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)
|
def infinity?(value)
|
||||||
value.respond_to?(:infinite?) && value.infinite?
|
value.respond_to?(:infinite?) && value.infinite?
|
||||||
end
|
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.
|
# - Type is an OID::Type object.
|
||||||
# This class has side effects on the +store+ passed during initialization.
|
# This class has side effects on the +store+ passed during initialization.
|
||||||
class TypeMapInitializer # :nodoc:
|
class TypeMapInitializer # :nodoc:
|
||||||
def initialize(store)
|
def initialize(store, run_complex_types = true)
|
||||||
@store = store
|
@store = store
|
||||||
|
@run_complex_types = run_complex_types
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(records)
|
def run(records)
|
||||||
|
|
|
@ -127,18 +127,15 @@ module ActiveRecord
|
||||||
bit_varying: OID::BitVarying,
|
bit_varying: OID::BitVarying,
|
||||||
binary: OID::Bytea,
|
binary: OID::Bytea,
|
||||||
cidr: OID::Cidr,
|
cidr: OID::Cidr,
|
||||||
date: OID::Date,
|
|
||||||
date_time: OID::DateTime,
|
date_time: OID::DateTime,
|
||||||
decimal: OID::Decimal,
|
decimal: OID::Decimal,
|
||||||
enum: OID::Enum,
|
enum: OID::Enum,
|
||||||
float: OID::Float,
|
|
||||||
hstore: OID::Hstore,
|
hstore: OID::Hstore,
|
||||||
inet: OID::Inet,
|
inet: OID::Inet,
|
||||||
json: OID::Json,
|
json: OID::Json,
|
||||||
jsonb: OID::Jsonb,
|
jsonb: OID::Jsonb,
|
||||||
money: OID::Money,
|
money: OID::Money,
|
||||||
point: OID::Point,
|
point: OID::Point,
|
||||||
time: OID::Time,
|
|
||||||
uuid: OID::Uuid,
|
uuid: OID::Uuid,
|
||||||
vector: OID::Vector,
|
vector: OID::Vector,
|
||||||
xml: OID::Xml,
|
xml: OID::Xml,
|
||||||
|
|
|
@ -255,6 +255,8 @@ module ActiveRecord
|
||||||
@table_alias_length = nil
|
@table_alias_length = nil
|
||||||
|
|
||||||
connect
|
connect
|
||||||
|
add_pg_decoders
|
||||||
|
|
||||||
@statements = StatementPool.new @connection,
|
@statements = StatementPool.new @connection,
|
||||||
self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
|
self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
|
||||||
|
|
||||||
|
@ -459,11 +461,11 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_type_map(m) # :nodoc:
|
def initialize_type_map(m) # :nodoc:
|
||||||
register_class_with_limit m, 'int2', OID::Integer
|
register_class_with_limit m, 'int2', Type::Integer
|
||||||
register_class_with_limit m, 'int4', OID::Integer
|
register_class_with_limit m, 'int4', Type::Integer
|
||||||
register_class_with_limit m, 'int8', OID::Integer
|
register_class_with_limit m, 'int8', Type::Integer
|
||||||
m.alias_type 'oid', 'int2'
|
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.alias_type 'float8', 'float4'
|
||||||
m.register_type 'text', Type::Text.new
|
m.register_type 'text', Type::Text.new
|
||||||
register_class_with_limit m, 'varchar', Type::String
|
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, 'bit', OID::Bit
|
||||||
register_class_with_limit m, 'varbit', OID::BitVarying
|
register_class_with_limit m, 'varbit', OID::BitVarying
|
||||||
m.alias_type 'timestamptz', 'timestamp'
|
m.alias_type 'timestamptz', 'timestamp'
|
||||||
m.register_type 'date', OID::Date.new
|
m.register_type 'date', Type::Date.new
|
||||||
m.register_type 'time', OID::Time.new
|
m.register_type 'time', Type::Time.new
|
||||||
|
|
||||||
m.register_type 'money', OID::Money.new
|
m.register_type 'money', OID::Money.new
|
||||||
m.register_type 'bytea', OID::Bytea.new
|
m.register_type 'bytea', OID::Bytea.new
|
||||||
|
@ -780,6 +782,36 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,13 @@ module ActiveRecord
|
||||||
private
|
private
|
||||||
|
|
||||||
def cast_value(value)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue