class ActiveRecord::ConnectionAdapters::PostgreSQLColumn

:nodoc:
PostgreSQL-specific extensions to column definitions in a table.

def self.binary_to_string(value)

Unescapes bytea output from a database to the binary string it represents.
def self.binary_to_string(value)
  # In each case, check if the value actually is escaped PostgreSQL bytea output
  # or an unescaped Active Record attribute that was just written.
  if PGconn.respond_to?(:unescape_bytea)
    self.class.module_eval do
      define_method(:binary_to_string) do |value|
        if value =~ /\\\d{3}/
          PGconn.unescape_bytea(value)
        else
          value
        end
      end
    end
  else
    self.class.module_eval do
      define_method(:binary_to_string) do |value|
        if value =~ /\\\d{3}/
          result = ''
          i, max = 0, value.size
          while i < max
            char = value[i]
            if char == ?\\
              if value[i+1] == ?\\
                char = ?\\
                i += 1
              else
                char = value[i+1..i+3].oct
                i += 3
              end
            end
            result << char
            i += 1
          end
          result
        else
          value
        end
      end
    end
  end
  self.class.binary_to_string(value)
end  

def self.extract_value_from_default(default)

Extracts the value from a PostgreSQL column default definition.
def self.extract_value_from_default(default)
  case default
    # Numeric types
    when /\A\(?(-?\d+(\.\d*)?\)?)\z/
      $1
    # Character types
    when /\A'(.*)'::(?:character varying|bpchar|text)\z/m
      $1
    # Character types (8.1 formatting)
    when /\AE'(.*)'::(?:character varying|bpchar|text)\z/m
      $1.gsub(/\\(\d\d\d)/) { $1.oct.chr }
    # 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
    # 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 self.string_to_binary(value)

Escapes binary strings for bytea input to the database.
def self.string_to_binary(value)
  if PGconn.respond_to?(:escape_bytea)
    self.class.module_eval do
      define_method(:string_to_binary) do |value|
        PGconn.escape_bytea(value) if value
      end
    end
  else
    self.class.module_eval do
      define_method(:string_to_binary) do |value|
        if value
          result = ''
          value.each_byte { |c| result << sprintf('\\\\%03o', c) }
          result
        end
      end
    end
  end
  self.class.string_to_binary(value)
end

def extract_limit(sql_type)

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

def extract_precision(sql_type)

Extracts the precision from PostgreSQL-specific data types.
def extract_precision(sql_type)
  # Actual code is defined dynamically in PostgreSQLAdapter.connect
  # depending on the server specifics
  super
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 initialize(name, default, sql_type = nil, null = true)

Instantiates a new PostgreSQL column definition in a table.
:nodoc:
PostgreSQL-specific extensions to column definitions in a table.
def initialize(name, default, sql_type = nil, null = true)
  super(name, self.class.extract_value_from_default(default), sql_type, null)
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
    # 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$/
      :string
    # Geometric types
    when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/
      :string
    # Network address types
    when /^(?:cidr|inet|macaddr)$/
      :string
    # Bit strings
    when /^bit(?: varying)?(?:\(\d+\))?$/
      :string
    # XML type
    when /^xml$/
      :string
    # Arrays
    when /^\D+\[\]$/
      :string              
    # Object identifier types
    when /^oid$/
      :integer
    # Pass through all types that are not specific to PostgreSQL.
    else
      super
  end
end