Skip to content

Commit 851618c

Browse files
committed
Merge pull request #31966 from kg8m/fix_limited_ids_for
Use column alias of primary_key in limited_ids_for
1 parent 853054b commit 851618c

File tree

6 files changed

+30
-17
lines changed

6 files changed

+30
-17
lines changed

activerecord/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
* Fix `#columns_for_distinct` of MySQL and PostgreSQL to make
2+
`ActiveRecord::FinderMethods#limited_ids_for` use correct primary key values
3+
even if `ORDER BY` columns include other table's primary key.
4+
5+
Fixes #28364.
6+
7+
*Takumi Kagiyama*
8+
19
* Make `reflection.klass` raise if `polymorphic?` not to be misused.
210

311
Fixes #31876.

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ def columns_for_distinct(columns, orders) # :nodoc:
515515
s.gsub(/\s+(?:ASC|DESC)\b/i, "")
516516
}.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
517517

518-
[super, *order_columns].join(", ")
518+
(order_columns << super).join(", ")
519519
end
520520

521521
def strict_mode?

activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ def columns_for_distinct(columns, orders) #:nodoc:
583583
.gsub(/\s+NULLS\s+(?:FIRST|LAST)\b/i, "")
584584
}.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
585585

586-
[super, *order_columns].join(", ")
586+
(order_columns << super).join(", ")
587587
end
588588

589589
def update_table_definition(table_name, base) # :nodoc:

activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,25 @@ def test_columns_for_distinct_zero_orders
2525
end
2626

2727
def test_columns_for_distinct_one_order
28-
assert_equal "posts.id, posts.created_at AS alias_0",
28+
assert_equal "posts.created_at AS alias_0, posts.id",
2929
@conn.columns_for_distinct("posts.id", ["posts.created_at desc"])
3030
end
3131

3232
def test_columns_for_distinct_few_orders
33-
assert_equal "posts.id, posts.created_at AS alias_0, posts.position AS alias_1",
33+
assert_equal "posts.created_at AS alias_0, posts.position AS alias_1, posts.id",
3434
@conn.columns_for_distinct("posts.id", ["posts.created_at desc", "posts.position asc"])
3535
end
3636

3737
def test_columns_for_distinct_with_case
3838
assert_equal(
39-
"posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0",
39+
"CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0, posts.id",
4040
@conn.columns_for_distinct("posts.id",
4141
["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"])
4242
)
4343
end
4444

4545
def test_columns_for_distinct_blank_not_nil_orders
46-
assert_equal "posts.id, posts.created_at AS alias_0",
46+
assert_equal "posts.created_at AS alias_0, posts.id",
4747
@conn.columns_for_distinct("posts.id", ["posts.created_at desc", "", " "])
4848
end
4949

@@ -52,7 +52,7 @@ def test_columns_for_distinct_with_arel_order
5252
def order.to_sql
5353
"posts.created_at desc"
5454
end
55-
assert_equal "posts.id, posts.created_at AS alias_0",
55+
assert_equal "posts.created_at AS alias_0, posts.id",
5656
@conn.columns_for_distinct("posts.id", [order])
5757
end
5858

activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,25 +263,25 @@ def test_columns_for_distinct_zero_orders
263263
end
264264

265265
def test_columns_for_distinct_one_order
266-
assert_equal "posts.id, posts.created_at AS alias_0",
266+
assert_equal "posts.created_at AS alias_0, posts.id",
267267
@connection.columns_for_distinct("posts.id", ["posts.created_at desc"])
268268
end
269269

270270
def test_columns_for_distinct_few_orders
271-
assert_equal "posts.id, posts.created_at AS alias_0, posts.position AS alias_1",
271+
assert_equal "posts.created_at AS alias_0, posts.position AS alias_1, posts.id",
272272
@connection.columns_for_distinct("posts.id", ["posts.created_at desc", "posts.position asc"])
273273
end
274274

275275
def test_columns_for_distinct_with_case
276276
assert_equal(
277-
"posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0",
277+
"CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0, posts.id",
278278
@connection.columns_for_distinct("posts.id",
279279
["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"])
280280
)
281281
end
282282

283283
def test_columns_for_distinct_blank_not_nil_orders
284-
assert_equal "posts.id, posts.created_at AS alias_0",
284+
assert_equal "posts.created_at AS alias_0, posts.id",
285285
@connection.columns_for_distinct("posts.id", ["posts.created_at desc", "", " "])
286286
end
287287

@@ -290,23 +290,23 @@ def test_columns_for_distinct_with_arel_order
290290
def order.to_sql
291291
"posts.created_at desc"
292292
end
293-
assert_equal "posts.id, posts.created_at AS alias_0",
293+
assert_equal "posts.created_at AS alias_0, posts.id",
294294
@connection.columns_for_distinct("posts.id", [order])
295295
end
296296

297297
def test_columns_for_distinct_with_nulls
298-
assert_equal "posts.title, posts.updater_id AS alias_0", @connection.columns_for_distinct("posts.title", ["posts.updater_id desc nulls first"])
299-
assert_equal "posts.title, posts.updater_id AS alias_0", @connection.columns_for_distinct("posts.title", ["posts.updater_id desc nulls last"])
298+
assert_equal "posts.updater_id AS alias_0, posts.title", @connection.columns_for_distinct("posts.title", ["posts.updater_id desc nulls first"])
299+
assert_equal "posts.updater_id AS alias_0, posts.title", @connection.columns_for_distinct("posts.title", ["posts.updater_id desc nulls last"])
300300
end
301301

302302
def test_columns_for_distinct_without_order_specifiers
303-
assert_equal "posts.title, posts.updater_id AS alias_0",
303+
assert_equal "posts.updater_id AS alias_0, posts.title",
304304
@connection.columns_for_distinct("posts.title", ["posts.updater_id"])
305305

306-
assert_equal "posts.title, posts.updater_id AS alias_0",
306+
assert_equal "posts.updater_id AS alias_0, posts.title",
307307
@connection.columns_for_distinct("posts.title", ["posts.updater_id nulls last"])
308308

309-
assert_equal "posts.title, posts.updater_id AS alias_0",
309+
assert_equal "posts.updater_id AS alias_0, posts.title",
310310
@connection.columns_for_distinct("posts.title", ["posts.updater_id nulls first"])
311311
end
312312

activerecord/test/cases/finder_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,11 @@ def test_find_with_order_on_included_associations_with_construct_finder_sql_for_
11801180
order("author_addresses_authors.id DESC").limit(3).to_a.size
11811181
end
11821182

1183+
def test_find_with_eager_loading_collection_and_ordering_by_collection_primary_key
1184+
assert_equal Post.first, Post.eager_load(comments: :ratings).
1185+
order("posts.id, ratings.id, comments.id").first
1186+
end
1187+
11831188
def test_find_with_nil_inside_set_passed_for_one_attribute
11841189
client_of = Company.
11851190
where(client_of: [2, 1, nil],

0 commit comments

Comments
 (0)