class ActiveRecord::ConnectionAdapters::PostgreSQLColumn

def self.extract_value_from_default(default)

Extracts the value from a PostgreSQL column default definition.
def self.extract_value_from_default(default)
  # This is a performance optimization for Ruby 1.9.2 in development.
  # If the value is nil, we return nil straight away without checking
  # the regular expressions. If we check each regular expression,
  # Regexp#=== will call NilClass#to_str, which will trigger
  # method_missing (defined by whiny nil in ActiveSupport) which
  # makes this method very very slow.
  return default unless default
  case default
    when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
      $1
    # Numeric types
    when /\A\(?(-?\d+(\.\d*)?\)?(::bigint)?)\z/
      $1
    # Character types
    when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
      $1.gsub(/''/, "'")
    # Binary data types
    when /\A'(.*)'::bytea\z/m
      $1
    # Date/time types
    when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
      $1
    when /\A'(.*)'::interval\z/
      $1
    # Boolean type
    when 'true'
      true
    when 'false'
      false
    # Geometric types
    when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
      $1
    # Network address types
    when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
      $1
    # Bit string types
    when /\AB'(.*)'::"?bit(?: varying)?"?\z/
      $1
    # XML type
    when /\A'(.*)'::xml\z/m
      $1
    # Arrays
    when /\A'(.*)'::"?\D+"?\[\]\z/
      $1
    # Hstore
    when /\A'(.*)'::hstore\z/
      $1
    # JSON
    when /\A'(.*)'::json\z/
      $1
    # Object identifier types
    when /\A-?\d+\z/
      $1
    else
      # Anything else is blank, some user type, or some function
      # and we can't know the value of that, so return nil.
      nil
  end
end

def accessor

def accessor
  @oid_type.accessor
end

def extract_limit(sql_type)

def extract_limit(sql_type)
  case sql_type
  when /^bigint/i;    8
  when /^smallint/i;  2
  when /^timestamp/i; nil
  else super
  end
end

def extract_precision(sql_type)

Extracts the precision from PostgreSQL-specific data types.
def extract_precision(sql_type)
  if sql_type == 'money'
    self.class.money_precision
  elsif sql_type =~ /timestamp/i
    $1.to_i if sql_type =~ /\((\d+)\)/
  else
    super
  end
end

def extract_scale(sql_type)

Extracts the scale from PostgreSQL-specific data types.
def extract_scale(sql_type)
  # Money type has a fixed scale of 2.
  sql_type =~ /^money/ ? 2 : super
end

def has_default_function?(default_value, default)

def has_default_function?(default_value, default)
  !default_value && (%r{\w+\(.*\)} === default)
end

def initialize(name, default, oid_type, sql_type = nil, null = true)

Instantiates a new PostgreSQL column definition in a table.
def initialize(name, default, oid_type, sql_type = nil, null = true)
  @oid_type = oid_type
  default_value     = self.class.extract_value_from_default(default)
  if sql_type =~ /\[\]$/
    @array = true
    super(name, default_value, sql_type[0..sql_type.length - 3], null)
  else
    @array = false
    super(name, default_value, sql_type, null)
  end
  @default_function = default if has_default_function?(default_value, default)
end

def simplified_type(field_type)

Maps PostgreSQL-specific data types to logical Rails types.
def simplified_type(field_type)
  case field_type
  # Numeric and monetary types
  when /^(?:real|double precision)$/
    :float
  # Monetary types
  when 'money'
    :decimal
  when 'hstore'
    :hstore
  when 'ltree'
    :ltree
  # Network address types
  when 'inet'
    :inet
  when 'cidr'
    :cidr
  when 'macaddr'
    :macaddr
  # Character types
  when /^(?:character varying|bpchar)(?:\(\d+\))?$/
    :string
  # Binary data types
  when 'bytea'
    :binary
  # Date/time types
  when /^timestamp with(?:out)? time zone$/
    :datetime
  when /^interval(?:|\(\d+\))$/
    :string
  # Geometric types
  when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/
    :string
  # Bit strings
  when /^bit(?: varying)?(?:\(\d+\))?$/
    :string
  # XML type
  when 'xml'
    :xml
  # tsvector type
  when 'tsvector'
    :tsvector
  # Arrays
  when /^\D+\[\]$/
    :string
  # Object identifier types
  when 'oid'
    :integer
  # UUID type
  when 'uuid'
    :uuid
  # JSON type
  when 'json'
    :json
  # Small and big integer types
  when /^(?:small|big)int$/
    :integer
  when /(num|date|tstz|ts|int4|int8)range$/
    field_type.to_sym
  # Pass through all types that are not specific to PostgreSQL.
  else
    super
  end
end

def type_cast(value)

def type_cast(value)
  return if value.nil?
  return super if encoded?
  @oid_type.type_cast value
end

def type_cast_for_write(value)

def type_cast_for_write(value)
  if @oid_type.respond_to?(:type_cast_for_write)
    @oid_type.type_cast_for_write(value)
  else
    super
  end
end