From ec53d0fa90bffe39fbde68238bd69cba5b40c680 Mon Sep 17 00:00:00 2001 From: Scott Woods Date: Sat, 4 Apr 2009 17:36:57 -0400 Subject: [PATCH 1/4] Introduce a table name that's capitalized (and associated test) to illustrate the fact that PostgreSQL blows up when dumping the schema. --- activerecord/test/cases/schema_dumper_test.rb | 5 +++++ activerecord/test/schema/schema.rb | 4 ++++ 2 files changed, 9 insertions(+), 0 deletions(-) diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 17e4c75..d9fa6c0 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -21,6 +21,11 @@ class SchemaDumperTest < ActiveRecord::TestCase output = standard_dump 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? diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index ea848a2..483ef14 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -67,6 +67,10 @@ ActiveRecord::Schema.define do create_table :booleantests, :force => true do |t| 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 -- 1.6.1 From 23b515855ce41c513ae0adf4bb903f449cba6932 Mon Sep 17 00:00:00 2001 From: Scott Woods Date: Sat, 4 Apr 2009 18:37:07 -0400 Subject: [PATCH 2/4] Quote table names when casting to regclass so that capitalized tables are supported. --- .../connection_adapters/postgresql_adapter.rb | 6 +++--- 1 files changed, 3 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 913bb52..13a23af 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -745,7 +745,7 @@ module ActiveRecord 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? @@ -764,7 +764,7 @@ module ActiveRecord 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 @@ -1040,7 +1040,7 @@ module ActiveRecord 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 -- 1.6.1 From 8c8aadb34f067925dc70cd81635c66f872060f97 Mon Sep 17 00:00:00 2001 From: Scott Woods Date: Sat, 4 Apr 2009 19:19:40 -0400 Subject: [PATCH 3/4] Add test to cover schema-prefixed capitalized table names. --- activerecord/test/cases/schema_test_postgresql.rb | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/activerecord/test/cases/schema_test_postgresql.rb b/activerecord/test/cases/schema_test_postgresql.rb index 336a387..35c6fba 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 = 'TableName' INDEX_A_NAME = 'a_index_things_on_name' INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema' INDEX_A_COLUMN = 'name' @@ -21,6 +22,7 @@ class SchemaTest < ActiveRecord::TestCase def setup @connection = ActiveRecord::Base.connection @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{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});" @@ -39,6 +41,12 @@ class SchemaTest < ActiveRecord::TestCase 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 -- 1.6.1 From ab1d8e40603040c29ac9a498716b11ae2a55bab2 Mon Sep 17 00:00:00 2001 From: Scott Woods Date: Sat, 4 Apr 2009 19:20:14 -0400 Subject: [PATCH 4/4] Override the default table quoting method to add support for postgresql schema prefixes. --- .../connection_adapters/postgresql_adapter.rb | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 13a23af..b4ba512 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -392,6 +392,24 @@ module ActiveRecord quote_string(s) end + # Quotes table names for use in SQL queries, respecting the optional + # schema that may be out front. + def quote_table_name(name) #:nodoc: + if name.respond_to?(:split) + # The name is a string. It could contain a schema, which shouldn't + # be included in the quotes. + schema, table_name = name.split('.') + if schema && table_name + %(#{schema}."#{table_name}") + else + quote_column_name(name) + end + else + # The name is a symbol. No need to check for a schema. + quote_column_name(name) + end + end + # Quotes column names for use in SQL queries. def quote_column_name(name) #:nodoc: %("#{name}") -- 1.6.1