The PostgreSQL adapter works both with the C-based (www.postgresql.jp/interfaces/ruby/) and the Ruby-base (available both as gem and from rubyforge.org/frs/?group_id=234&release_id=1145) drivers.

Options:

  • :host -- Defaults to localhost

  • :port -- Defaults to 5432

  • :username -- Defaults to nothing

  • :password -- Defaults to nothing

  • :database -- The name of the database. No default, must be provided.

  • :schema_search_path -- An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.

  • :encoding -- An optional client encoding that is using in a SET client_encoding TO <encoding> call on connection.

  • :min_messages -- An optional client min messages that is using in a SET client_min_messages TO <min_messages> call on connection.

  • :allow_concurrency -- If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.

Methods
A
D
N
P
Q
R
S
T
Constants
BYTEA_COLUMN_TYPE_OID = 17
 
NUMERIC_COLUMN_TYPE_OID = 1700
 
TIMESTAMPOID = 1114
 
TIMESTAMPTZOID = 1184
 
Class Public methods
new(connection, logger, config = {})
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 55
def initialize(connection, logger, config = {})
  super(connection, logger)
  @config = config
  @async = config[:allow_concurrency]
  configure_connection
end
Instance Public methods
active?()

Is this connection alive and ready for queries?

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 63
def active?
  if @connection.respond_to?(:status)
    @connection.status == PGconn::CONNECTION_OK
  else
    @connection.query 'SELECT 1'
    true
  end
# postgres-pr raises a NoMethodError when querying if no conn is available
rescue PGError, NoMethodError
  false
end
adapter_name()
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 51
def adapter_name
  'PostgreSQL'
end
add_column(table_name, column_name, type, options = {})
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 316
def add_column(table_name, column_name, type, options = {})
  default = options[:default]
  notnull = options[:null] == false

  # Add the column.
  execute("ALTER TABLE #{table_name} ADD COLUMN #{column_name} #{type_to_sql(type, options[:limit])}")

  # Set optional default. If not null, update nulls to the new default.
  if options_include_default?(options)
    change_column_default(table_name, column_name, default)
    if notnull
      execute("UPDATE #{table_name} SET #{column_name}=#{quote(default, options[:column])} WHERE #{column_name} IS NULL")
    end
  end

  if notnull
    execute("ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL")
  end
end
add_order_by_for_association_limiting!(sql, options)

ORDER BY clause for the passed order option.

PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this by wrapping the sql as a sub-select and ordering in that query.

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 403
def add_order_by_for_association_limiting!(sql, options)
  return sql if options[:order].blank?
  
  order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
  order.map! { |s| 'DESC' if s =~ %r\bdesc$/ }
  order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
  
  sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
end
default_sequence_name(table_name, pk = nil)
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 243
def default_sequence_name(table_name, pk = nil)
  default_pk, default_seq = pk_and_sequence_for(table_name)
  default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
end
disconnect!()
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 84
def disconnect!
  # Both postgres and postgres-pr respond to :close
  @connection.close rescue nil
end
distinct(columns, order_by)

SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.

PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and requires that the ORDER BY include the distinct column.

distinct("posts.id", "posts.created_at desc")
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 384
def distinct(columns, order_by)
  return "DISTINCT #{columns}" if order_by.blank?

  # construct a clean list of column names from the ORDER BY clause, removing
  # any asc/desc modifiers
  order_columns = order_by.split(',').collect { |s| s.split.first }
  order_columns.delete_if &:blank?
  order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }

  # return a DISTINCT ON() clause that's distinct on the columns we want but includes
  # all the required columns for the ORDER BY to work properly
  sql = "DISTINCT ON (#{columns}) #{columns}, "
  sql << order_columns * ', '
end
native_database_types()
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 89
def native_database_types
  {
    :primary_key => "serial primary key",
    :string      => { :name => "character varying", :limit => 255 },
    :text        => { :name => "text" },
    :integer     => { :name => "integer" },
    :float       => { :name => "float" },
    :decimal     => { :name => "decimal" },
    :datetime    => { :name => "timestamp" },
    :timestamp   => { :name => "timestamp" },
    :time        => { :name => "time" },
    :date        => { :name => "date" },
    :binary      => { :name => "bytea" },
    :boolean     => { :name => "boolean" }
  }
end
pk_and_sequence_for(table)

Find a table’s primary key and sequence.

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 267
      def pk_and_sequence_for(table)
        # First try looking for a sequence with a dependency on the
        # given table's primary key.
        result = query("          SELECT attr.attname, name.nspname, seq.relname
          FROM pg_class      seq,
               pg_attribute  attr,
               pg_depend     dep,
               pg_namespace  name,
               pg_constraint cons
          WHERE seq.oid           = dep.objid
            AND seq.relnamespace  = name.oid
            AND seq.relkind       = 'S'
            AND attr.attrelid     = dep.refobjid
            AND attr.attnum       = dep.refobjsubid
            AND attr.attrelid     = cons.conrelid
            AND attr.attnum       = cons.conkey[1]
            AND cons.contype      = 'p'
            AND dep.refobjid      = '#{table}'::regclass
", 'PK and serial sequence')[0]

        if result.nil? or result.empty?
          # If that fails, try parsing the primary key's default value.
          # Support the 7.x and 8.0 nextval('foo'::text) as well as
          # the 8.1+ nextval('foo'::regclass).
          # TODO: assumes sequence is in same schema as table.
          result = query("            SELECT attr.attname, name.nspname, split_part(def.adsrc, '''', 2)
            FROM pg_class       t
            JOIN pg_namespace   name ON (t.relnamespace = name.oid)
            JOIN pg_attribute   attr ON (t.oid = attrelid)
            JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
            JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
            WHERE t.oid = '#{table}'::regclass
              AND cons.contype = 'p'
              AND def.adsrc ~* 'nextval'
", 'PK and custom sequence')[0]
        end
        # check for existence of . in sequence name as in public.foo_sequence.  if it does not exist, return unqualified sequence
        # We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path
        [result.first, result.last]
      rescue
        nil
      end
quote(value, column = nil)

QUOTING ==================================================

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 116
def quote(value, column = nil)
  if value.kind_of?(String) && column && column.type == :binary
    "'#{escape_bytea(value)}'"
  else
    super
  end
end
quote_column_name(name)
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 124
def quote_column_name(name)
  %Q("#{name}")
end
quoted_date(value)
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 128
def quoted_date(value)
  value.strftime("%Y-%m-%d %H:%M:%S.#{sprintf("%06d", value.usec)}")
end
reconnect!()

Close then reopen the connection.

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 76
def reconnect!
  # TODO: postgres-pr doesn't have PGconn#reset.
  if @connection.respond_to?(:reset)
    @connection.reset
    configure_connection
  end
end
rename_table(name, new_name)
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 312
def rename_table(name, new_name)
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
end
reset_pk_sequence!(table, pk = nil, sequence = nil)

Resets sequence to the max value of the table’s pk if present.

# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 249
      def reset_pk_sequence!(table, pk = nil, sequence = nil)
        unless pk and sequence
          default_pk, default_sequence = pk_and_sequence_for(table)
          pk ||= default_pk
          sequence ||= default_sequence
        end
        if pk
          if sequence
            select_value "              SELECT setval('#{sequence}', (SELECT COALESCE(MAX(#{pk})+(SELECT increment_by FROM #{sequence}), (SELECT min_value FROM #{sequence})) FROM #{table}), false)
", 'Reset sequence'
          else
            @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger
          end
        end
      end
supports_migrations?()
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 106
def supports_migrations?
  true
end
table_alias_length()
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 110
def table_alias_length
  63
end