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

Changeset 5888

Show
Ignore:
Timestamp:
01/12/07 05:24:07 (3 years ago)
Author:
bitsweat
Message:

Merge [5887] from trunk. References #4668.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1-2-pre-release/activerecord/CHANGELOG

    r5867 r5888  
    11*SVN* 
    22 
     3* PostgreSQL: use a subselect to correctly perform eager finds with :limit and :order.  #4668 [eventualbuddha] 
     4 
    35* Fix the Oracle adapter for serialized attributes stored in CLOBs.  Closes #6825 [mschoen, tdfowler] 
    46 
     
    68 
    79* [DOCS] Document :allow_nil option of #validate_uniqueness_of. Closes #3143 [Caio Chassot] 
     10 
    811 
    912*1.15.0 RC2* (r5847, January 4th, 2007) 
  • branches/1-2-pre-release/activerecord/lib/active_record/associations.rb

    r5752 r5888  
    12061206 
    12071207          add_conditions!(sql, options[:conditions], scope) 
    1208           sql << "ORDER BY #{options[:order]} " if options[:order] 
     1208          if options[:order] 
     1209            if is_distinct 
     1210              connection.add_order_by_for_association_limiting!(sql, options) 
     1211            else 
     1212              sql << "ORDER BY #{options[:order]}" 
     1213            end 
     1214          end 
    12091215          add_limit!(sql, options, scope) 
    12101216          return sanitize_sql(sql) 
  • branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb

    r5481 r5888  
    288288        "DISTINCT #{columns}" 
    289289      end 
     290       
     291      # ORDER BY clause for the passed order option. 
     292      # PostgreSQL overrides this due to its stricter standards compliance. 
     293      def add_order_by_for_association_limiting!(sql, options) 
     294        sql << "ORDER BY #{options[:order]}" 
     295      end 
    290296    end 
    291297  end 
  • branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

    r5481 r5888  
    384384        # construct a clean list of column names from the ORDER BY clause, removing 
    385385        # any asc/desc modifiers 
    386         order_columns = order_by.split(',').collect! { |s| s.split.first } 
     386        order_columns = order_by.split(',').collect { |s| s.split.first } 
    387387        order_columns.delete_if &:blank? 
    388  
    389         # add the DISTINCT columns to the start of the ORDER BY clause 
    390         order_by.replace "#{columns}, #{order_by}" 
     388        order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" } 
    391389 
    392390        # return a DISTINCT ON() clause that's distinct on the columns we want but includes 
     
    394392        sql = "DISTINCT ON (#{columns}) #{columns}, " 
    395393        sql << order_columns * ', ' 
     394      end 
     395       
     396      # ORDER BY clause for the passed order option. 
     397      #  
     398      # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this 
     399      # by wrapping the sql as a sub-select and ordering in that query. 
     400      def add_order_by_for_association_limiting!(sql, options) 
     401        return sql if options[:order].blank? 
     402         
     403        order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?) 
     404        order.map! { |s| 'DESC' if s =~ /\bdesc$/i } 
     405        order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ') 
     406         
     407        sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}" 
    396408      end 
    397409 
  • branches/1-2-pre-release/activerecord/test/associations/eager_test.rb

    r5840 r5888  
    290290  def find_all_ordered(className, include=nil) 
    291291    className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include) 
     292  end 
     293   
     294  def test_limited_eager_with_order 
     295    assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1) 
     296    assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1) 
     297  end 
     298   
     299  def test_limited_eager_with_multiple_order_columns 
     300    assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1) 
     301    assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1) 
    292302  end 
    293303