Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #12955 from joshwilliams/master

Postgres schema: Constrain sequence search classid
  • Loading branch information...
commit 850f59fb29fac7a0cbe91bb4b70f0cd02cac143e 2 parents 656f4f2 + 0110d7b
@senny senny authored
View
5 activerecord/CHANGELOG.md
@@ -22,6 +22,11 @@
*Matthew Draper*
+* `pk_and_sequence_for` now ensures that only the pg_depend entries
+ pointing to pg_class, and thus only sequence objects, are considered.
+
+ *Josh Williams*
+
* `where.not` adds `references` for `includes` like normal `where` calls do.
Fixes #14406.
View
1  activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -327,6 +327,7 @@ def pk_and_sequence_for(table) #:nodoc:
AND attr.attrelid = cons.conrelid
AND attr.attnum = cons.conkey[1]
AND cons.contype = 'p'
+ AND dep.classid = 'pg_class'::regclass
AND dep.refobjid = '#{quote_table_name(table)}'::regclass
end_sql
View
45 activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -176,6 +176,51 @@ def test_pk_and_sequence_for_returns_nil_if_table_not_found
assert_nil @connection.pk_and_sequence_for('unobtainium')
end
+ def test_pk_and_sequence_for_with_collision_pg_class_oid
+ @connection.exec_query('create table ex(id serial primary key)')
+ @connection.exec_query('create table ex2(id serial primary key)')
+
+ correct_depend_record = [
+ "'pg_class'::regclass",
+ "'ex_id_seq'::regclass",
+ '0',
+ "'pg_class'::regclass",
+ "'ex'::regclass",
+ '1',
+ "'a'"
+ ]
+
+ collision_depend_record = [
+ "'pg_attrdef'::regclass",
+ "'ex2_id_seq'::regclass",
+ '0',
+ "'pg_class'::regclass",
+ "'ex'::regclass",
+ '1',
+ "'a'"
+ ]
+
+ @connection.exec_query(
+ "DELETE FROM pg_depend WHERE objid = 'ex_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'"
+ )
+ @connection.exec_query(
+ "INSERT INTO pg_depend VALUES(#{collision_depend_record.join(',')})"
+ )
+ @connection.exec_query(
+ "INSERT INTO pg_depend VALUES(#{correct_depend_record.join(',')})"
+ )
+
+ seq = @connection.pk_and_sequence_for('ex').last
+ assert_equal 'ex_id_seq', seq
+
+ @connection.exec_query(
+ "DELETE FROM pg_depend WHERE objid = 'ex2_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'"
+ )
+ ensure
+ @connection.exec_query('DROP TABLE IF EXISTS ex')
+ @connection.exec_query('DROP TABLE IF EXISTS ex2')
+ end
+
def test_exec_insert_number
with_example_table do
insert(@connection, 'number' => 10)
Please sign in to comment.
Something went wrong with that request. Please try again.