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.
This commit is contained in:
Tom Hughes 2010-06-14 13:00:49 +01:00
parent a0af70cfb4
commit f980e7e4a6

View 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