Skip to content

Commit

Permalink
Handle array option in type_to_sql
Browse files Browse the repository at this point in the history
`[]` is a part of `sql_type`, so it is always necessary to respect to
array option when `type_to_sql` is called.
  • Loading branch information
kamipo committed Feb 19, 2015
1 parent 7ba2cd0 commit 9ec2d4a
Showing 1 changed file with 16 additions and 19 deletions.
Expand Up @@ -5,8 +5,7 @@ class SchemaCreation < AbstractAdapter::SchemaCreation
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
Expand Down Expand Up @@ -408,14 +407,12 @@ 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_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
Expand Down Expand Up @@ -513,8 +510,8 @@ def index_name_length
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.
Expand All @@ -530,24 +527,24 @@ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
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
Expand Down

0 comments on commit 9ec2d4a

Please sign in to comment.