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. Closes #6156.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5586 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper 2006-11-20 08:54:42 +00:00
parent 3fc4771996
commit 19c99acfbc
4 changed files with 41 additions and 4 deletions

@ -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]

@ -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 @@ def self.mysql_connection(config) # :nodoc:
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

@ -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

@ -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 (