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
Constants
BYTEA_COLUMN_TYPE_OID = 17
NUMERIC_COLUMN_TYPE_OID = 1700
TIMESTAMPOID = 1114
TIMESTAMPTZOID = 1184
Public Class methods
new(connection, logger, config = {})
    # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 55
55:       def initialize(connection, logger, config = {})
56:         super(connection, logger)
57:         @config = config
58:         @async = config[:allow_concurrency]
59:         configure_connection
60:       end
Public Instance methods
active?()

Is this connection alive and ready for queries?

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 63
63:       def active?
64:         if @connection.respond_to?(:status)
65:           @connection.status == PGconn::CONNECTION_OK
66:         else
67:           @connection.query 'SELECT 1'
68:           true
69:         end
70:       # postgres-pr raises a NoMethodError when querying if no conn is available
71:       rescue PGError, NoMethodError
72:         false
73:       end
adapter_name()
    # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 51
51:       def adapter_name
52:         'PostgreSQL'
53:       end
add_column(table_name, column_name, type, options = {})
     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 321
321:       def add_column(table_name, column_name, type, options = {})
322:         default = options[:default]
323:         notnull = options[:null] == false
324: 
325:         # Add the column.
326:         execute("ALTER TABLE #{table_name} ADD COLUMN #{column_name} #{type_to_sql(type, options[:limit])}")
327: 
328:         # Set optional default. If not null, update nulls to the new default.
329:         if options_include_default?(options)
330:           change_column_default(table_name, column_name, default)
331:           if notnull
332:             execute("UPDATE #{table_name} SET #{column_name}=#{quote(default, options[:column])} WHERE #{column_name} IS NULL")
333:           end
334:         end
335: 
336:         if notnull
337:           execute("ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL")
338:         end
339:       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 vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 408
408:       def add_order_by_for_association_limiting!(sql, options)
409:         return sql if options[:order].blank?
410:         
411:         order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
412:         order.map! { |s| 'DESC' if s =~ /\bdesc$/i }
413:         order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
414:         
415:         sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
416:       end
default_sequence_name(table_name, pk = nil)
     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 245
245:       def default_sequence_name(table_name, pk = nil)
246:         default_pk, default_seq = pk_and_sequence_for(table_name)
247:         default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
248:       end
disconnect!()
    # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 84
84:       def disconnect!
85:         # Both postgres and postgres-pr respond to :close
86:         @connection.close rescue nil
87:       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 vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 389
389:       def distinct(columns, order_by)
390:         return "DISTINCT #{columns}" if order_by.blank?
391: 
392:         # construct a clean list of column names from the ORDER BY clause, removing
393:         # any asc/desc modifiers
394:         order_columns = order_by.split(',').collect { |s| s.split.first }
395:         order_columns.delete_if &:blank?
396:         order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
397: 
398:         # return a DISTINCT ON() clause that's distinct on the columns we want but includes
399:         # all the required columns for the ORDER BY to work properly
400:         sql = "DISTINCT ON (#{columns}) #{columns}, "
401:         sql << order_columns * ', '
402:       end
native_database_types()
     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 89
 89:       def native_database_types
 90:         {
 91:           :primary_key => "serial primary key",
 92:           :string      => { :name => "character varying", :limit => 255 },
 93:           :text        => { :name => "text" },
 94:           :integer     => { :name => "integer" },
 95:           :float       => { :name => "float" },
 96:           :decimal     => { :name => "decimal" },
 97:           :datetime    => { :name => "timestamp" },
 98:           :timestamp   => { :name => "timestamp" },
 99:           :time        => { :name => "time" },
100:           :date        => { :name => "date" },
101:           :binary      => { :name => "bytea" },
102:           :boolean     => { :name => "boolean" }
103:         }
104:       end
pk_and_sequence_for(table)

Find a table‘s primary key and sequence.

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 270
270:       def pk_and_sequence_for(table)
271:         # First try looking for a sequence with a dependency on the
272:         # given table's primary key.
273:         result = query("SELECT attr.attname, name.nspname, seq.relname\nFROM pg_class      seq,\npg_attribute  attr,\npg_depend     dep,\npg_namespace  name,\npg_constraint cons\nWHERE seq.oid           = dep.objid\nAND seq.relnamespace  = name.oid\nAND seq.relkind       = 'S'\nAND attr.attrelid     = dep.refobjid\nAND attr.attnum       = dep.refobjsubid\nAND attr.attrelid     = cons.conrelid\nAND attr.attnum       = cons.conkey[1]\nAND cons.contype      = 'p'\nAND dep.refobjid      = '\#{table}'::regclass\n", 'PK and serial sequence')[0]
274: 
275:         if result.nil? or result.empty?
276:           # If that fails, try parsing the primary key's default value.
277:           # Support the 7.x and 8.0 nextval('foo'::text) as well as
278:           # the 8.1+ nextval('foo'::regclass).
279:           # TODO: assumes sequence is in same schema as table.
280:           result = query("SELECT attr.attname, name.nspname, split_part(def.adsrc, '''', 2)\nFROM pg_class       t\nJOIN pg_namespace   name ON (t.relnamespace = name.oid)\nJOIN pg_attribute   attr ON (t.oid = attrelid)\nJOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)\nJOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])\nWHERE t.oid = '\#{table}'::regclass\nAND cons.contype = 'p'\nAND def.adsrc ~* 'nextval'\n", 'PK and custom sequence')[0]
281:         end
282:         # check for existence of . in sequence name as in public.foo_sequence.  if it does not exist, return unqualified sequence
283:         # We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path
284:         [result.first, result.last]
285:       rescue
286:         nil
287:       end
quote(value, column = nil)

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

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

Close then reopen the connection.

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

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

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 251
251:       def reset_pk_sequence!(table, pk = nil, sequence = nil)
252:         unless pk and sequence
253:           default_pk, default_sequence = pk_and_sequence_for(table)
254:           pk ||= default_pk
255:           sequence ||= default_sequence
256:         end
257:         if pk
258:           if sequence
259:             select_value "SELECT setval('\#{sequence}', (SELECT COALESCE(MAX(\#{pk})+(SELECT increment_by FROM \#{sequence}), (SELECT min_value FROM \#{sequence})) FROM \#{table}), false)\n", 'Reset sequence'
260:           else
261:             @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger
262:           end
263:         end
264:       end
supports_migrations?()
     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 106
106:       def supports_migrations?
107:         true
108:       end
table_alias_length()
     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 110
110:       def table_alias_length
111:         63
112:       end