]> git.openstreetmap.org Git - rails.git/blob - config/initializers/postgresql_adapter.rb
Merge branch 'master' into openid
[rails.git] / config / initializers / postgresql_adapter.rb
1 if defined?(ActiveRecord::ConnectionAdaptors::PostgreSQLAdaptor)
2   module ActiveRecord
3     module ConnectionAdapters
4       class PostgreSQLAdapter
5         def pk_and_sequence_for(table)
6           # First try looking for a sequence with a dependency on the
7           # given table's primary key.
8           result = query(<<-end_sql, 'PK and serial sequence')[0]
9             SELECT attr.attname, seq.relname
10             FROM pg_class      seq,
11                  pg_attribute  attr,
12                  pg_depend     dep,
13                  pg_namespace  name,
14                  pg_constraint cons
15             WHERE seq.oid           = dep.objid
16               AND seq.relkind       = 'S'
17               AND attr.attrelid     = dep.refobjid
18               AND attr.attnum       = dep.refobjsubid
19               AND attr.attrelid     = cons.conrelid
20               AND attr.attnum       = cons.conkey[1]
21               AND cons.contype      = 'p'
22               AND dep.classid       = '"pg_class"'::regclass
23               AND dep.refclassid    = '"pg_class"'::regclass
24               AND dep.refobjid      = '#{quote_table_name(table)}'::regclass
25           end_sql
26   
27           if result.nil? or result.empty?
28             # If that fails, try parsing the primary key's default value.
29             # Support the 7.x and 8.0 nextval('foo'::text) as well as
30             # the 8.1+ nextval('foo'::regclass).
31             result = query(<<-end_sql, 'PK and custom sequence')[0]
32               SELECT attr.attname,
33                 CASE
34                   WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
35                     substr(split_part(def.adsrc, '''', 2),
36                            strpos(split_part(def.adsrc, '''', 2), '.')+1)
37                   ELSE split_part(def.adsrc, '''', 2)
38                 END
39               FROM pg_class       t
40               JOIN pg_attribute   attr ON (t.oid = attrelid)
41               JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
42               JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
43               WHERE t.oid = '#{quote_table_name(table)}'::regclass
44                 AND cons.contype = 'p'
45                 AND def.adsrc ~* 'nextval'
46             end_sql
47           end
48   
49           # [primary_key, sequence]
50           [result.first, result.last]
51         rescue
52           nil
53         end
54       end
55     end
56   end
57 end