Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 5586

Show
Ignore:
Timestamp:
11/20/06 08:54:42 (2 years ago)
Author:
bitsweat
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r5564 r5586  
    11*SVN* 
     2 
     3* 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] 
    24 
    35* Simplify association proxy implementation by factoring construct_scope out of method_missing.  #6643 [martin] 
  • trunk/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb

    r5533 r5586  
    11require 'active_record/connection_adapters/abstract_adapter' 
     2require 'set' 
    23 
    34module MysqlCompat 
     
    8586  module ConnectionAdapters 
    8687    class MysqlColumn < Column #:nodoc: 
     88      TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:binary, :string, :text]) 
     89 
     90      def initialize(name, default, sql_type = nil, null = true) 
     91        super 
     92        self.default = nil if missing_default_forged_as_empty_string? 
     93      end 
     94 
    8795      private 
    8896        def simplified_type(field_type) 
     
    9098          return :string  if field_type =~ /enum/i 
    9199          super 
     100        end 
     101 
     102        # MySQL misreports NOT NULL column default when none is given. 
     103        # We can't detect this for columns which may have a legitimate '' 
     104        # default (string, text, binary) but we can for others (integer, 
     105        # datetime, boolean, and the rest). 
     106        # 
     107        # Test whether the column has default '', is not null, and is not 
     108        # a type allowing default ''. 
     109        def missing_default_forged_as_empty_string? 
     110          !null && default == '' && !TYPES_ALLOWING_EMPTY_STRING_DEFAULT.include?(type) 
    92111        end 
    93112    end 
  • trunk/activerecord/test/defaults_test.rb

    r4596 r5586  
    11require 'abstract_unit' 
    22require 'fixtures/default' 
     3require 'fixtures/entrant' 
    34 
    4 if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter) 
    5   class DefaultsTest < Test::Unit::TestCase 
     5class DefaultTest < Test::Unit::TestCase 
     6  def test_nil_defaults_for_not_null_columns 
     7    column_defaults = 
     8      if current_adapter?(:MysqlAdapter) 
     9        { 'id' => nil, 'name' => '', 'course_id' => 0 } 
     10      else 
     11        { 'id' => nil, 'name' => nil, 'course_id' => nil } 
     12      end 
     13 
     14    column_defaults.each do |name, default| 
     15      column = Entrant.columns_hash[name] 
     16      assert !column.null, "#{name} column should be NOT NULL" 
     17      assert_equal default, column.default, "#{name} column should be DEFAULT #{default.inspect}" 
     18    end 
     19  end 
     20 
     21  if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter, :FirebirdAdapter, :OpenBaseAdapter) 
    622    def test_default_integers 
    723      default = Default.new 
  • trunk/activerecord/test/fixtures/db_definitions/postgresql.sql

    r4596 r5586  
    131131CREATE TABLE entrants ( 
    132132  id serial, 
    133   name text
    134   course_id integer 
     133  name text not null
     134  course_id integer not null 
    135135); 
    136136