From f980e7e4a61e11e73406ed236398904a9ee2b30b Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 14 Jun 2010 13:00:49 +0100 Subject: [PATCH] Completely replace rails' version of pk_and_sequence_for Falling back to the rails code for pk_and_sequence_for doesn't work because we still wind up retrying the slow version of the query for tables with no primary key. So just replace it instead. --- config/initializers/postgresql_adapter.rb | 31 +++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/config/initializers/postgresql_adapter.rb b/config/initializers/postgresql_adapter.rb index 0420a7495..c5a69a1d9 100644 --- a/config/initializers/postgresql_adapter.rb +++ b/config/initializers/postgresql_adapter.rb @@ -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 -- 2.43.2