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:
parent
af7a6e57cd
commit
d568fb6137
@ -1,16 +1,15 @@
|
|||||||
*SVN*
|
*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]
|
* 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]
|
* 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.]
|
* 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]
|
* 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]
|
* Refactor ActiveRecord::Base.reset_subclasses to #reset, and add global observer resetting. [Rick Olson]
|
||||||
|
|
||||||
* Formally deprecate the deprecated finders. [Koz]
|
* Formally deprecate the deprecated finders. [Koz]
|
||||||
|
@ -315,8 +315,9 @@ def pk_and_sequence_for(table)
|
|||||||
AND def.adsrc ~* 'nextval'
|
AND def.adsrc ~* 'nextval'
|
||||||
end_sql
|
end_sql
|
||||||
end
|
end
|
||||||
# check for existence of . in sequence name as in public.foo_sequence. if it does not exist, join the current namespace
|
# check for existence of . in sequence name as in public.foo_sequence. if it does not exist, return unqualified sequence
|
||||||
result.last['.'] ? [result.first, result.last] : [result.first, "#{result[1]}.#{result[2]}"]
|
# We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path
|
||||||
|
[result.first, result.last]
|
||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
75
activerecord/test/schema_authorization_test_postgresql.rb
Normal file
75
activerecord/test/schema_authorization_test_postgresql.rb
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user