aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2006-08-09 03:25:39 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2006-08-09 03:25:39 +0000
commitd568fb61373074e015083ad39e0dc8168e81733b (patch)
tree6ec552512558f180e0a84f14ee2045831bffec7e
parentaf7a6e57cd718a6ca2182bfb7ee441ad3c1158fb (diff)
downloadrails-d568fb61373074e015083ad39e0dc8168e81733b.tar.gz
rails-d568fb61373074e015083ad39e0dc8168e81733b.tar.bz2
rails-d568fb61373074e015083ad39e0dc8168e81733b.zip
PostgreSQL: autodetected sequences work correctly with multiple schemas. Rely on the schema search_path instead of explicitly qualifying the sequence name with its schema. Closes #5280.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4737 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--activerecord/CHANGELOG5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb5
-rw-r--r--activerecord/test/schema_authorization_test_postgresql.rb75
3 files changed, 80 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index c9ffa888cb..37b367f4f1 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,16 +1,15 @@
*SVN*
-<<<<<<< .mine
+* PostgreSQL: autodetected sequences work correctly with multiple schemas. Rely on the schema search_path instead of explicitly qualifying the sequence name with its schema. #5280 [guy.naor@famundo.com]
+
* Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
-=======
* Cache nil results for has_one associations so multiple calls don't call the database. Closes #5757. [Michael A. Schoen]
* Add documentation for how to disable timestamps on a per model basis. Closes #5684. [matt@mattmargolis.net Marcel Molina Jr.]
* Don't save has_one associations unnecessarily. #5735 [Jonathan Viney]
->>>>>>> .r4727
* Refactor ActiveRecord::Base.reset_subclasses to #reset, and add global observer resetting. [Rick Olson]
* Formally deprecate the deprecated finders. [Koz]
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 94584a5ea4..d2a65fec3f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -315,8 +315,9 @@ module ActiveRecord
AND def.adsrc ~* 'nextval'
end_sql
end
- # check for existence of . in sequence name as in public.foo_sequence. if it does not exist, join the current namespace
- result.last['.'] ? [result.first, result.last] : [result.first, "#{result[1]}.#{result[2]}"]
+ # check for existence of . in sequence name as in public.foo_sequence. if it does not exist, return unqualified sequence
+ # We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path
+ [result.first, result.last]
rescue
nil
end
diff --git a/activerecord/test/schema_authorization_test_postgresql.rb b/activerecord/test/schema_authorization_test_postgresql.rb
new file mode 100644
index 0000000000..f13287658c
--- /dev/null
+++ b/activerecord/test/schema_authorization_test_postgresql.rb
@@ -0,0 +1,75 @@
+require 'abstract_unit'
+
+class SchemaThing < ActiveRecord::Base
+end
+
+class SchemaAuthorizationTest < Test::Unit::TestCase
+ self.use_transactional_fixtures = false
+
+ TABLE_NAME = 'schema_things'
+ COLUMNS = [
+ 'id serial primary key',
+ 'name character varying(50)'
+ ]
+ USERS = ['rails_pg_schema_user1', 'rails_pg_schema_user2']
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ @connection.execute "SET search_path TO '$user',public"
+ set_session_auth
+ USERS.each do |u|
+ @connection.execute "CREATE ROLE #{u}"
+ @connection.execute "CREATE SCHEMA AUTHORIZATION #{u}"
+ set_session_auth u
+ @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
+ @connection.execute "INSERT INTO #{TABLE_NAME} (name) VALUES ('#{u}')"
+ set_session_auth
+ end
+ end
+
+ def teardown
+ set_session_auth
+ @connection.execute "RESET search_path"
+ USERS.each do |u|
+ @connection.execute "DROP SCHEMA #{u} CASCADE"
+ @connection.execute "DROP ROLE #{u}"
+ end
+ end
+
+ def test_schema_invisible
+ assert_raise(ActiveRecord::StatementInvalid) do
+ set_session_auth
+ @connection.execute "SELECT * FROM #{TABLE_NAME}"
+ end
+ end
+
+ def test_schema_uniqueness
+ assert_nothing_raised do
+ set_session_auth
+ USERS.each do |u|
+ set_session_auth u
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
+ set_session_auth
+ end
+ end
+ end
+
+ def test_sequence_schema_caching
+ assert_nothing_raised do
+ USERS.each do |u|
+ set_session_auth u
+ st = SchemaThing.new :name => 'TEST1'
+ st.save!
+ st = SchemaThing.new :id => 5, :name => 'TEST2'
+ st.save!
+ set_session_auth
+ end
+ end
+ end
+
+ private
+ def set_session_auth auth = nil
+ @connection.execute "SET SESSION AUTHORIZATION #{auth || 'default'}"
+ end
+
+end