aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2008-06-10 18:31:37 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2008-06-10 18:31:37 -0700
commit03bf72721900049ce18750767a22cf8091886c07 (patch)
treeabdf69800e343cc764ffc4e63493adfc8dc4ad5e /activerecord
parentb440aeb54a969ec25228881dd02eb019bbfd7c1e (diff)
downloadrails-03bf72721900049ce18750767a22cf8091886c07.tar.gz
rails-03bf72721900049ce18750767a22cf8091886c07.tar.bz2
rails-03bf72721900049ce18750767a22cf8091886c07.zip
PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb23
2 files changed, 22 insertions, 3 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index a65771648e..a899bfbd52 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*
+* PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later. [Jeremy Kemper]
+
* Added SQL escaping for :limit and :offset in MySQL [Jonathan Wiess]
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)