]> git.openstreetmap.org Git - rails.git/blobdiff - config/initializers/postgresql_adapter.rb
Completely replace rails' version of pk_and_sequence_for
[rails.git] / config / initializers / postgresql_adapter.rb
index 0420a7495896ba1eff779f36d8438bcbc94f4316..c5a69a1d9baa3444ac16a3ddd12895bb5b399f26 100644 (file)
@@ -1,9 +1,9 @@
 module ActiveRecord
   module ConnectionAdapters
     class PostgreSQLAdapter
-      alias_method :old_pk_and_sequence_for, :pk_and_sequence_for
-
       def pk_and_sequence_for(table)
+        # First try looking for a sequence with a dependency on the
+        # given table's primary key.
         result = query(<<-end_sql, 'PK and serial sequence')[0]
           SELECT attr.attname, seq.relname
           FROM pg_class      seq,
@@ -24,10 +24,31 @@ module ActiveRecord
         end_sql
 
         if result.nil? or result.empty?
-          old_pk_and_sequence_for(table)
-        else
-          [result.first, result.last]
+          # 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).
+          result = query(<<-end_sql, 'PK and custom sequence')[0]
+            SELECT attr.attname,
+              CASE
+                WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
+                  substr(split_part(def.adsrc, '''', 2),
+                         strpos(split_part(def.adsrc, '''', 2), '.')+1)
+                ELSE split_part(def.adsrc, '''', 2)
+              END
+            FROM pg_class       t
+            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 = '#{quote_table_name(table)}'::regclass
+              AND cons.contype = 'p'
+              AND def.adsrc ~* 'nextval'
+          end_sql
         end
+
+        # [primary_key, sequence]
+        [result.first, result.last]
+      rescue
+        nil
       end
     end
   end