From 64b33b6cf9db508d2c12394cc1a3f36c91fb2eed Mon Sep 17 00:00:00 2001 From: Scott Woods Date: Mon, 20 Apr 2009 23:48:02 +0300 Subject: [PATCH] Quote table names when casting to regclass so that capitalized tables are supported. [#2418 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tarmo Tänav --- .../connection_adapters/postgresql_adapter.rb | 6 ++--- activerecord/test/cases/schema_dumper_test.rb | 5 +++++ .../test/cases/schema_test_postgresql.rb | 22 +++++++++++++++++++ activerecord/test/schema/schema.rb | 4 ++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 15e155d025af3..74ee6a133f2fa 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -764,7 +764,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.refobjid = '#{table}'::regclass + AND dep.refobjid = '#{quote_table_name(table)}'::regclass end_sql if result.nil? or result.empty? @@ -783,7 +783,7 @@ def pk_and_sequence_for(table) #:nodoc: JOIN pg_attribute attr ON (t.oid = attrelid) JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum) JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1]) - WHERE t.oid = '#{table}'::regclass + WHERE t.oid = '#{quote_table_name(table)}'::regclass AND cons.contype = 'p' AND def.adsrc ~* 'nextval' end_sql @@ -1059,7 +1059,7 @@ def column_definitions(table_name) #:nodoc: SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull FROM pg_attribute a LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum - WHERE a.attrelid = '#{table_name}'::regclass + WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum end_sql diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 17e4c755ce4f8..0b1a075b9845d 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -22,6 +22,11 @@ def test_schema_dump_excludes_sqlite_sequence assert_no_match %r{create_table "sqlite_sequence"}, output end + def test_schema_dump_includes_camelcase_table_name + output = standard_dump + assert_match %r{create_table "CamelCase"}, output + end + def assert_line_up(lines, pattern, required = false) return assert(true) if lines.empty? matches = lines.map { |line| line.match(pattern) } diff --git a/activerecord/test/cases/schema_test_postgresql.rb b/activerecord/test/cases/schema_test_postgresql.rb index ed8e1d22e376a..a294848fa3679 100644 --- a/activerecord/test/cases/schema_test_postgresql.rb +++ b/activerecord/test/cases/schema_test_postgresql.rb @@ -6,6 +6,7 @@ class SchemaTest < ActiveRecord::TestCase SCHEMA_NAME = 'test_schema' SCHEMA2_NAME = 'test_schema2' TABLE_NAME = 'things' + CAPITALIZED_TABLE_NAME = 'Things' INDEX_A_NAME = 'a_index_things_on_name' INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema' INDEX_A_COLUMN = 'name' @@ -30,10 +31,15 @@ class Thing3 < ActiveRecord::Base set_table_name 'test_schema."things.table"' end + class Thing4 < ActiveRecord::Base + set_table_name 'test_schema."Things"' + end + def setup @connection = ActiveRecord::Base.connection @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})" @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})" + @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})" @connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})" @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});" @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});" @@ -52,6 +58,12 @@ def test_with_schema_prefixed_table_name end end + def test_with_schema_prefixed_capitalized_table_name + assert_nothing_raised do + assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{CAPITALIZED_TABLE_NAME}") + end + end + def test_with_schema_search_path assert_nothing_raised do with_schema_search_path(SCHEMA_NAME) do @@ -74,21 +86,31 @@ def test_classes_with_qualified_schema_name assert_equal 0, Thing1.count assert_equal 0, Thing2.count assert_equal 0, Thing3.count + assert_equal 0, Thing4.count Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) assert_equal 1, Thing1.count assert_equal 0, Thing2.count assert_equal 0, Thing3.count + assert_equal 0, Thing4.count Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) assert_equal 1, Thing1.count assert_equal 1, Thing2.count assert_equal 0, Thing3.count + assert_equal 0, Thing4.count Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) assert_equal 1, Thing1.count assert_equal 1, Thing2.count assert_equal 1, Thing3.count + assert_equal 0, Thing4.count + + Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) + assert_equal 1, Thing1.count + assert_equal 1, Thing2.count + assert_equal 1, Thing3.count + assert_equal 1, Thing4.count end def test_raise_on_unquoted_schema_name diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 5640510c96a0d..3b073b0888742 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -68,6 +68,10 @@ def create_table(*args, &block) t.boolean :value end + create_table "CamelCase", :force => true do |t| + t.string :name + end + create_table :categories, :force => true do |t| t.string :name, :null => false t.string :type