Changeset 5888
- Timestamp:
- 01/12/07 05:24:07 (3 years ago)
- Files:
-
- branches/1-2-pre-release/activerecord/CHANGELOG (modified) (2 diffs)
- branches/1-2-pre-release/activerecord/lib/active_record/associations.rb (modified) (1 diff)
- branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb (modified) (1 diff)
- branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb (modified) (2 diffs)
- branches/1-2-pre-release/activerecord/test/associations/eager_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/1-2-pre-release/activerecord/CHANGELOG
r5867 r5888 1 1 *SVN* 2 2 3 * PostgreSQL: use a subselect to correctly perform eager finds with :limit and :order. #4668 [eventualbuddha] 4 3 5 * Fix the Oracle adapter for serialized attributes stored in CLOBs. Closes #6825 [mschoen, tdfowler] 4 6 … … 6 8 7 9 * [DOCS] Document :allow_nil option of #validate_uniqueness_of. Closes #3143 [Caio Chassot] 10 8 11 9 12 *1.15.0 RC2* (r5847, January 4th, 2007) branches/1-2-pre-release/activerecord/lib/active_record/associations.rb
r5752 r5888 1206 1206 1207 1207 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 1209 1215 add_limit!(sql, options, scope) 1210 1216 return sanitize_sql(sql) branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
r5481 r5888 288 288 "DISTINCT #{columns}" 289 289 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 290 296 end 291 297 end branches/1-2-pre-release/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
r5481 r5888 384 384 # construct a clean list of column names from the ORDER BY clause, removing 385 385 # 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 } 387 387 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}" } 391 389 392 390 # return a DISTINCT ON() clause that's distinct on the columns we want but includes … … 394 392 sql = "DISTINCT ON (#{columns}) #{columns}, " 395 393 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}" 396 408 end 397 409 branches/1-2-pre-release/activerecord/test/associations/eager_test.rb
r5840 r5888 290 290 def find_all_ordered(className, include=nil) 291 291 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) 292 302 end 293 303