﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37353	"QuerySet.values(""pk"").distinct().order_by() on a composite primary key silently truncates the primary key"	Dave Gaeddert		"Selecting a composite primary key with `values()` / `values_list()`, combined with `distinct()` and `order_by()` on a field that isn't selected, returns the primary key with a component missing:

{{{
class Tenant(models.Model):
    pass

class User(models.Model):
    pk = models.CompositePrimaryKey(""tenant_id"", ""id"")
    tenant = models.ForeignKey(Tenant, models.CASCADE)
    id = models.SmallIntegerField(unique=True)
    email = models.EmailField(unique=True)

User.objects.values(""pk"").distinct().order_by(""email"")
# [{'pk': (1,)}, {'pk': (1,)}, {'pk': (2,)}]
# expected [{'pk': (1, 1)}, {'pk': (1, 2)}, {'pk': (2, 3)}]

User.objects.values(""pk"", ""id"").distinct().order_by(""email"")
# IndexError: list index out of range
}}}

No exception in the first case — silent data loss. Reproduces on 5.2, 6.0, and main, on both PostgreSQL 16 and SQLite.

Cause: ordering by an unselected field with `distinct()` appends that field to the select clause via `get_extra_select()`, and the extra column is then stripped from each row by slicing with `SQLCompiler.col_count`. `col_count` is the number of ''selections'', but a `CompositePrimaryKey` is one selection compiled to N columns, so the slice cuts into the primary key itself.

Found while verifying the fix for #37222. Jacob Walls agreed this is a bug on the PR thread: https://github.com/django/django/pull/21659#discussion_r3899304732

Fix with a regression test on my fork: https://github.com/davegaeddert/django/pull/6 — happy to open it against main if accepted.

(AI assistance: Claude Code was used to find and reproduce this and draft the fix; I verified the reproducer and test results.)"	Bug	new	Database layer (models, ORM)	5.2	Normal		composite primary key		Unreviewed	0	0	0	0	0	0
