From 949b1336266d3de25d5d84911c7a43f7da3121bf Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sat, 14 Feb 2015 07:46:10 +0900 Subject: Should handle array option for `:cast_as` --- .../connection_adapters/postgresql/schema_statements.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 81fde18f64..87122fc00e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -407,12 +407,16 @@ module ActiveRecord def change_column(table_name, column_name, type, options = {}) clear_cache! quoted_table_name = quote_table_name(table_name) + quoted_column_name = quote_column_name(column_name) sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale]) sql_type << "[]" if options[:array] - sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}" - sql << " USING #{options[:using]}" if options[:using] - if options[:cast_as] - sql << " USING CAST(#{quote_column_name(column_name)} AS #{type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale])})" + sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}" + if options[:using] + sql << " USING #{options[:using]}" + elsif options[:cast_as] + cast_as_type = type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale]) + cast_as_type << "[]" if options[:array] + sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})" end execute sql -- cgit v1.2.3 From 7ba2cd06a215f4f1f48e61957dda9ca4a880d0a4 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sun, 15 Feb 2015 08:51:31 +0900 Subject: Use `delegate` to call the methods to `@conn` --- .../connection_adapters/abstract/schema_creation.rb | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb index bc8fa9b6cf..f754df93b6 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb @@ -18,6 +18,9 @@ module ActiveRecord "ADD #{accept(o)}" end + delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql, to: :@conn + private :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql + private def visit_AlterTable(o) @@ -70,18 +73,6 @@ module ActiveRecord column_options end - def quote_column_name(name) - @conn.quote_column_name name - end - - def quote_table_name(name) - @conn.quote_table_name name - end - - def type_to_sql(type, limit, precision, scale) - @conn.type_to_sql type.to_sym, limit, precision, scale - end - def add_column_options!(sql, options) sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options) # must explicitly check for :null to allow change_column to work on migrations @@ -97,10 +88,6 @@ module ActiveRecord sql end - def quote_default_expression(value, column) - @conn.quote_default_expression(value, column) - end - def options_include_default?(options) options.include?(:default) && !(options[:null] == false && options[:default].nil?) end -- cgit v1.2.3 From 9ec2d4a39b0e4ee3cbae6f2ed93fb8a86c2d6936 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 10 Feb 2015 20:58:19 +0900 Subject: Handle array option in `type_to_sql` `[]` is a part of `sql_type`, so it is always necessary to respect to array option when `type_to_sql` is called. --- .../postgresql/schema_statements.rb | 35 ++++++++++------------ 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 87122fc00e..76f568ac03 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -5,8 +5,7 @@ module ActiveRecord private def visit_ColumnDefinition(o) - o.sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale) - o.sql_type << '[]' if o.array + o.sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale, o.array) super end end @@ -408,14 +407,12 @@ module ActiveRecord clear_cache! quoted_table_name = quote_table_name(table_name) quoted_column_name = quote_column_name(column_name) - sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale]) - sql_type << "[]" if options[:array] + sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale], options[:array]) sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}" if options[:using] sql << " USING #{options[:using]}" elsif options[:cast_as] - cast_as_type = type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale]) - cast_as_type << "[]" if options[:array] + cast_as_type = type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale], options[:array]) sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})" end execute sql @@ -513,8 +510,8 @@ module ActiveRecord end # Maps logical Rails types to PostgreSQL-specific data types. - def type_to_sql(type, limit = nil, precision = nil, scale = nil) - case type.to_s + def type_to_sql(type, limit = nil, precision = nil, scale = nil, array = nil) + sql = case type.to_s when 'binary' # PostgreSQL doesn't support limits on binary (bytea) columns. # The hard limit is 1Gb, because of a 32-bit size field, and TOAST. @@ -530,24 +527,24 @@ module ActiveRecord else raise(ActiveRecordError, "The limit on text can be at most 1GB - 1byte.") end when 'integer' - return 'integer' unless limit - case limit - when 1, 2; 'smallint' - when 3, 4; 'integer' - when 5..8; 'bigint' - else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.") + when 1, 2; 'smallint' + when nil, 3, 4; 'integer' + when 5..8; 'bigint' + else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.") end when 'datetime' - return super unless precision - case precision - when 0..6; "timestamp(#{precision})" - else raise(ActiveRecordError, "No timestamp type has precision of #{precision}. The allowed range of precision is from 0 to 6") + when nil; super(type, limit, precision, scale) + when 0..6; "timestamp(#{precision})" + else raise(ActiveRecordError, "No timestamp type has precision of #{precision}. The allowed range of precision is from 0 to 6") end else - super + super(type, limit, precision, scale) end + + sql << '[]' if array && type != :primary_key + sql end # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and -- cgit v1.2.3