From 6051323d4519db5014e7a7ce052c30453422ce6e Mon Sep 17 00:00:00 2001 From: Anuj Dutta Date: Tue, 1 Mar 2011 22:05:27 +0000 Subject: [PATCH] Added the code to fix the mysql integer limit issue. [#6049 state:resolved] --- .../abstract/schema_definitions.rb | 4 +- .../abstract/schema_statements.rb | 2 +- .../active_record/connection_adapters/column.rb | 6 ++++- .../connection_adapters/mysql2_adapter.rb | 20 +++++++++++++++++ .../connection_adapters/mysql_adapter.rb | 9 +++++++ .../connection_adapters/postgresql_adapter.rb | 9 +++++++ activerecord/test/cases/migration_test.rb | 23 ++++++++++++++++++++ 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 7ac48c6..98a59f8 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -31,7 +31,7 @@ module ActiveRecord add_column_options!(column_sql, column_options) unless type.to_sym == :primary_key column_sql end - + private def add_column_options!(sql, options) @@ -273,7 +273,7 @@ module ActiveRecord def to_sql @columns.map { |c| c.to_sql } * ', ' end - + private def native @base.native_database_types diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 3ec7dd0..7946342 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -66,7 +66,7 @@ module ActiveRecord def column_exists?(table_name, column_name, type = nil, options = {}) columns(table_name).any?{ |c| c.name == column_name.to_s && (!type || c.type == type) && - (!options[:limit] || c.limit == options[:limit]) && + (!options[:limit] || c.limit_exists?(options[:limit])) && (!options[:precision] || c.precision == options[:precision]) && (!options[:scale] || c.scale == options[:scale]) } end diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index 4e3d8a0..a7289f6 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -50,7 +50,11 @@ module ActiveRecord def has_default? !default.nil? end - + + def limit_exists?(new_limit) + limit == new_limit + end + # Returns the Ruby class that corresponds to the abstract data type. def klass case type diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb index 7bad511..ffa468a 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -42,6 +42,15 @@ module ActiveRecord super end + def limit_exists?(new_limit) + return super unless type.to_s == 'integer' + + case new_limit + when 5..8; limit == 8 + when nil, 4, 11; limit == 4 + else super end + end + private def simplified_type(field_type) return :boolean if Mysql2Adapter.emulate_booleans && field_type.downcase.index(BOOL) @@ -422,6 +431,17 @@ module ActiveRecord columns end + def limit_exists?(existing_limit, new_limit) + case new_limit + when 5..8 + existing_limit == 8 + when nil, 4, 11 + existing_limit == 4 + else + existing_limit == new_limit + end + end + def create_table(table_name, options = {}) super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB")) end diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 368c5b2..1c14c57 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -92,6 +92,15 @@ module ActiveRecord super end + def limit_exists?(new_limit) + return super unless type.to_s == 'integer' + + case new_limit + when 5..8; limit == 8 + when nil, 4, 11; limit == 4 + else super end + end + private def simplified_type(field_type) return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase.index("tinyint(1)") diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 576450b..f899b50 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -39,6 +39,15 @@ module ActiveRecord end # :startdoc: + def limit_exists?(new_limit) + return super unless type.to_s == 'integer' + + case new_limit + when 1, 2; limit == 2 + when 5..8; limit == 8 + else super end + end + private def extract_limit(sql_type) case sql_type diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 9d7c497..42c5bcf 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1071,6 +1071,29 @@ if ActiveRecord::Base.connection.supports_migrations? Person.connection.drop_table :testings rescue nil end + def test_column_exists_with_integer_limit + Person.connection.create_table :testings do |t| + t.column :one_int, :integer, :limit => 1 + t.column :four_int, :integer, :limit => 4 + t.column :eight_int, :integer, :limit => 8 + t.column :eleven_int, :integer, :limit => 11 + end + + if current_adapter?(:PostgreSQLAdapter) + Person.connection.column_exists?(:testings, :one_int, :integer, :limit => 1) + Person.connection.column_exists?(:testings, :four_int, :integer, :limit => 4) + Person.connection.column_exists?(:testings, :eight_int, :integer, :limit => 8) + elsif current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) + assert Person.connection.column_exists?(:testings, :one_int, :integer, :limit => 1) + assert Person.connection.column_exists?(:testings, :four_int, :integer, :limit => 4) + assert Person.connection.column_exists?(:testings, :eight_int, :integer, :limit => 8) + assert Person.connection.column_exists?(:testings, :eleven_int, :integer, :limit => 11) + end + ensure + Person.connection.drop_table :testings rescue nil + end + + def test_add_table assert !Reminder.table_exists? -- 1.6.3.2