Skip to content

fix(query): count and restrict expressions with an empty primary key - #1605

Open
dimitri-yatsenko wants to merge 1 commit into
masterfrom
fix/empty-primary-key-queries
Open

dimitri-yatsenko wants to merge 1 commit into
masterfrom
fix/empty-primary-key-queries

Conversation

@dimitri-yatsenko

Copy link
Copy Markdown
Member

An expression with an empty primary key, such as dj.U() & T or
dj.U().aggr(T, n="count(*)"), holds at most one row. Two operations on
such expressions failed:

  • len() took the single-column branch and generated
    count(DISTINCT ), which is invalid SQL. It now returns 0 or 1 by
    checking whether the row exists.
  • Restricting a dj.U() aggregation hit a bare assert in
    Aggregation.make_sql. Removing the assert alone would not have been
    enough: the MySQL branch emitted HAVING only together with GROUP BY,
    so the restriction would have been dropped without notice. MySQL now
    emits HAVING without GROUP BY, and PostgreSQL takes the subquery path
    whenever the aggregation is restricted, with or without grouping
    attributes.

Restriction conditions on an aggregation are now joined with str(), as
the base where_clause already does, so restricting any aggregation by
False no longer raises TypeError.

Closes #1581
Closes #1580

An expression with an empty primary key, such as `dj.U() & T` or
`dj.U().aggr(T, n="count(*)")`, holds at most one row. Two operations on
such expressions failed:

- `len()` took the single-column branch and generated
  `count(DISTINCT )`, which is invalid SQL. It now returns 0 or 1 by
  checking whether the row exists.
- Restricting a `dj.U()` aggregation hit a bare assert in
  `Aggregation.make_sql`. Removing the assert alone would not have been
  enough: the MySQL branch emitted HAVING only together with GROUP BY,
  so the restriction would have been dropped without notice. MySQL now
  emits HAVING without GROUP BY, and PostgreSQL takes the subquery path
  whenever the aggregation is restricted, with or without grouping
  attributes.

Restriction conditions on an aggregation are now joined with str(), as
the base where_clause already does, so restricting any aggregation by
False no longer raises TypeError.

Closes #1581
Closes #1580
@dimitri-yatsenko dimitri-yatsenko added this to the v2.4 milestone Oct 17, 2026
@dimitri-yatsenko dimitri-yatsenko added the bug Indicates an unexpected problem or unintended behavior label Oct 17, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Indicates an unexpected problem or unintended behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

len() of an expression with an empty primary key generates invalid SQL Restricting a dj.U() aggregation raises a bare AssertionError

1 participant