From 03bf72721900049ce18750767a22cf8091886c07 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 10 Jun 2008 18:31:37 -0700 Subject: PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later. --- .../connection_adapters/postgresql_adapter.rb | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 8a66ec82f9..e759a74faf 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -323,6 +323,12 @@ module ActiveRecord has_support end + def supports_insert_with_returning? + @supports_insert_with_returning ||= + @connection.respond_to?(:server_version) && + @connection.server_version >= 80200 + end + # Returns the configured supported identifier length supported by PostgreSQL, # or report the default of 63 on PostgreSQL 7.x. def table_alias_length @@ -415,12 +421,23 @@ module ActiveRecord # Executes an INSERT query and returns the new record's ID def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) + # Extract the table from the insert sql. Yuck. + table = sql.split(" ", 4)[2].gsub('"', '') + + # Try an insert with 'returning id' if available (PG >= 8.2) + if supports_insert_with_returning? + pk, sequence_name = *pk_and_sequence_for(table) unless pk + if pk + id = select_value("#{sql} RETURNING #{quote_column_name(pk)}") + clear_query_cache + return id + end + end + + # Otherwise, insert then grab last_insert_id. if insert_id = super insert_id else - # Extract the table from the insert sql. Yuck. - table = sql.split(" ", 4)[2].gsub('"', '') - # If neither pk nor sequence name is given, look them up. unless pk || sequence_name pk, sequence_name = *pk_and_sequence_for(table) -- cgit v1.2.3