aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb19
-rw-r--r--activerecord/test/defaults_test.rb20
-rw-r--r--activerecord/test/fixtures/db_definitions/postgresql.sql4
4 files changed, 41 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 67b0291bcd..a8a4170a20 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* MySQL: detect when a NOT NULL column without a default value is misreported as default ''. Can't detect for string, text, and binary columns since '' is a legitimate default. #6156 [simon@redhillconsulting.com.au, obrie, Jeremy Kemper]
+
* Simplify association proxy implementation by factoring construct_scope out of method_missing. #6643 [martin]
* Oracle: automatically detect the primary key. #6594 [vesaria, Michael Schoen]
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 6c75896233..574196e351 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -1,4 +1,5 @@
require 'active_record/connection_adapters/abstract_adapter'
+require 'set'
module MysqlCompat
# add all_hashes method to standard mysql-c bindings or pure ruby version
@@ -84,12 +85,30 @@ module ActiveRecord
module ConnectionAdapters
class MysqlColumn < Column #:nodoc:
+ TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:binary, :string, :text])
+
+ def initialize(name, default, sql_type = nil, null = true)
+ super
+ self.default = nil if missing_default_forged_as_empty_string?
+ end
+
private
def simplified_type(field_type)
return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase.index("tinyint(1)")
return :string if field_type =~ /enum/i
super
end
+
+ # MySQL misreports NOT NULL column default when none is given.
+ # We can't detect this for columns which may have a legitimate ''
+ # default (string, text, binary) but we can for others (integer,
+ # datetime, boolean, and the rest).
+ #
+ # Test whether the column has default '', is not null, and is not
+ # a type allowing default ''.
+ def missing_default_forged_as_empty_string?
+ !null && default == '' && !TYPES_ALLOWING_EMPTY_STRING_DEFAULT.include?(type)
+ end
end
# The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with
diff --git a/activerecord/test/defaults_test.rb b/activerecord/test/defaults_test.rb
index aba3c66de4..f15f422dc7 100644
--- a/activerecord/test/defaults_test.rb
+++ b/activerecord/test/defaults_test.rb
@@ -1,8 +1,24 @@
require 'abstract_unit'
require 'fixtures/default'
+require 'fixtures/entrant'
-if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter)
- class DefaultsTest < Test::Unit::TestCase
+class DefaultTest < Test::Unit::TestCase
+ def test_nil_defaults_for_not_null_columns
+ column_defaults =
+ if current_adapter?(:MysqlAdapter)
+ { 'id' => nil, 'name' => '', 'course_id' => 0 }
+ else
+ { 'id' => nil, 'name' => nil, 'course_id' => nil }
+ end
+
+ column_defaults.each do |name, default|
+ column = Entrant.columns_hash[name]
+ assert !column.null, "#{name} column should be NOT NULL"
+ assert_equal default, column.default, "#{name} column should be DEFAULT #{default.inspect}"
+ end
+ end
+
+ if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter, :FirebirdAdapter, :OpenBaseAdapter)
def test_default_integers
default = Default.new
assert_instance_of Fixnum, default.positive_integer
diff --git a/activerecord/test/fixtures/db_definitions/postgresql.sql b/activerecord/test/fixtures/db_definitions/postgresql.sql
index ce2c775aba..b5412c7400 100644
--- a/activerecord/test/fixtures/db_definitions/postgresql.sql
+++ b/activerecord/test/fixtures/db_definitions/postgresql.sql
@@ -130,8 +130,8 @@ CREATE TABLE auto_id_tests (
CREATE TABLE entrants (
id serial,
- name text,
- course_id integer
+ name text not null,
+ course_id integer not null
);
CREATE TABLE colnametests (