Permalink
Browse files

Merge [5586], [5596] from trunk.

git-svn-id: http://svn-commit.rubyonrails.org/rails/branches/1-2-pre-release@5599 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent ef6c3c4 commit 2043513f4cfaa682ede34c3b051dc66c9b2591c9 @jeremy jeremy committed Nov 20, 2006
View
2 activerecord/CHANGELOG
@@ -2,6 +2,8 @@
* Quote ActiveSupport::Multibyte::Chars. #6653 [Julian Tarkhanov]
+* 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, Jonathan Viney, Jeremy Kemper]
+
* validates_numericality_of uses \A \Z to ensure the entire string matches rather than ^ $ which may match one valid line of a multiline string. #5716 [Andreas Schwarz]
* Oracle: automatically detect the primary key. #6594 [vesaria, Michael Schoen]
View
20 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,31 @@ 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)
+ @original_default = default
+ super
+ @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 && @original_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
View
20 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' => nil }
+ 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
View
4 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 (

0 comments on commit 2043513

Please sign in to comment.