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]