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
This commit is contained in:
Jeremy Kemper 2006-08-09 03:25:39 +00:00
parent af7a6e57cd
commit d568fb6137
3 changed files with 80 additions and 5 deletions

@ -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]

@ -315,8 +315,9 @@ def pk_and_sequence_for(table)
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

@ -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