2   module ConnectionAdapters
 
   3     class PostgreSQLAdapter
 
   4       def pk_and_sequence_for(table)
 
   5         # First try looking for a sequence with a dependency on the
 
   6         # given table's primary key.
 
   7         result = query(<<-end_sql, 'PK and serial sequence')[0]
 
   8           SELECT attr.attname, seq.relname
 
  14           WHERE seq.oid           = dep.objid
 
  16             AND attr.attrelid     = dep.refobjid
 
  17             AND attr.attnum       = dep.refobjsubid
 
  18             AND attr.attrelid     = cons.conrelid
 
  19             AND attr.attnum       = cons.conkey[1]
 
  20             AND cons.contype      = 'p'
 
  21             AND dep.classid       = '"pg_class"'::regclass
 
  22             AND dep.refclassid    = '"pg_class"'::regclass
 
  23             AND dep.refobjid      = '#{quote_table_name(table)}'::regclass
 
  26         if result.nil? or result.empty?
 
  27           # If that fails, try parsing the primary key's default value.
 
  28           # Support the 7.x and 8.0 nextval('foo'::text) as well as
 
  29           # the 8.1+ nextval('foo'::regclass).
 
  30           result = query(<<-end_sql, 'PK and custom sequence')[0]
 
  33                 WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
 
  34                   substr(split_part(def.adsrc, '''', 2),
 
  35                          strpos(split_part(def.adsrc, '''', 2), '.')+1)
 
  36                 ELSE split_part(def.adsrc, '''', 2)
 
  39             JOIN pg_attribute   attr ON (t.oid = attrelid)
 
  40             JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
 
  41             JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
 
  42             WHERE t.oid = '#{quote_table_name(table)}'::regclass
 
  43               AND cons.contype = 'p'
 
  44               AND def.adsrc ~* 'nextval'
 
  48         # [primary_key, sequence]
 
  49         [result.first, result.last]