@@ -118,7 +118,6 @@ class SQLServerColumn < Column #:nodoc:
118118 def initialize ( name , default , sql_type = nil , null = true , sqlserver_options = { } )
119119 super ( name , default , sql_type , null )
120120 @sqlserver_options = sqlserver_options
121- @limit = nil unless limitable?
122121 end
123122
124123 def is_identity?
@@ -205,10 +204,13 @@ def new_time(year, mon, mday, hour, min, sec, microsec = 0)
205204
206205 private
207206
208- def limitable?
209- # SQL Server only supports limits on *char and float types. Although for schema dumping purposes
210- # it is useful to know what others are like bigint and smallint. So we trump #extract_limit.
211- [ :float , :string ] . include? ( type ) || ( type == :integer && sql_type =~ /^(big|small)int/i )
207+ def extract_limit ( sql_type )
208+ case sql_type
209+ when /^smallint/i then 2
210+ when /^int/i then 4
211+ when /^bigint/i then 8
212+ else super
213+ end
212214 end
213215
214216 def simplified_type ( field_type )
@@ -271,6 +273,15 @@ class SQLServerAdapter < AbstractAdapter
271273 ADAPTER_NAME = 'SQLServer' . freeze
272274 DATABASE_VERSION_REGEXP = /Microsoft SQL Server\s +(\d {4})/
273275 SUPPORTED_VERSIONS = [ 2000 , 2005 ] . freeze
276+ LIMITABLE_TYPES = [ :string , :integer , :float ] . freeze
277+
278+ class << self
279+
280+ def type_limitable? ( type )
281+ LIMITABLE_TYPES . include? ( type . to_sym )
282+ end
283+
284+ end
274285
275286 def initialize ( connection , logger , connection_options = nil )
276287 super ( connection , logger )
@@ -464,20 +475,20 @@ def empty_insert_statement(table_name)
464475 # SCHEMA STATEMENTS ========================================#
465476
466477 def native_database_types
467- txt = sqlserver_2005? ? "varchar(max)" : "text "
468- bin = sqlserver_2005? ? "varbinary(max)" : "image"
478+ text = sqlserver_2005? ? "varchar(max)" : "varchar(8000) "
479+ binary = sqlserver_2005? ? "varbinary(max)" : "image"
469480 {
470481 :primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY" ,
471482 :string => { :name => "varchar" , :limit => 255 } ,
472- :text => { :name => txt } ,
473- :integer => { :name => "int" } ,
483+ :text => { :name => text } ,
484+ :integer => { :name => "int" , :limit => 4 } ,
474485 :float => { :name => "float" , :limit => 8 } ,
475486 :decimal => { :name => "decimal" } ,
476487 :datetime => { :name => "datetime" } ,
477488 :timestamp => { :name => "datetime" } ,
478489 :time => { :name => "datetime" } ,
479490 :date => { :name => "datetime" } ,
480- :binary => { :name => bin } ,
491+ :binary => { :name => binary } ,
481492 :boolean => { :name => "bit" }
482493 }
483494 end
@@ -589,19 +600,16 @@ def add_order_by_for_association_limiting!(sql, options)
589600 end
590601
591602 def type_to_sql ( type , limit = nil , precision = nil , scale = nil )
592- # Remove limit for data types which do not require it
593- # Valid: ALTER TABLE sessions ALTER COLUMN [data] varchar(max)
594- # Invalid: ALTER TABLE sessions ALTER COLUMN [data] varchar(max)(16777215)
595- limit = nil if %w{ text varchar(max) nvarchar(max) ntext varbinary(max) image } . include? ( native_database_types [ type . to_sym ] [ :name ] )
596- return super unless type . to_s == 'integer'
597- if limit . nil?
598- 'integer'
599- elsif limit > 4
600- 'bigint'
601- elsif limit < 3
602- 'smallint'
603+ limit = nil unless self . class . type_limitable? ( type )
604+ if type . to_s == 'integer'
605+ case limit
606+ when 1 ..2 then 'smallint'
607+ when 3 ..4 , nil then 'integer'
608+ when 5 ..8 then 'bigint'
609+ else raise ( ActiveRecordError , "No integer type has byte size #{ limit } . Use a numeric with precision 0 instead." )
610+ end
603611 else
604- 'integer'
612+ super
605613 end
606614 end
607615
0 commit comments