Skip to content

feat(analysis): allow grouped counts and cast-typed projections - #58

Merged
omer-cengel merged 2 commits into
masterfrom
feature/grouped-count-and-cast-projections
Oct 3, 2026
Merged

omer-cengel merged 2 commits into
masterfrom
feature/grouped-count-and-cast-projections

Conversation

@omer-cengel

Copy link
Copy Markdown
Member

Summary

Queries can now report grouped counts and computed values. An aliased COUNT(*) may appear beside other SELECT items, so SELECT city, COUNT(*) AS venues ... GROUP BY city compiles, and a projection whose type is stated by a cast, such as SUM(amount)::numeric AS total, becomes a typed result component.

Changes

  • An aliased COUNT(*) is no longer required to be the only SELECT item; it is a non-null Long component in its own position beside direct columns, wildcards, cast projections, or other counts.
  • A projection written as <expression>::type AS alias or CAST(<expression> AS type) AS alias (with or without AS) becomes a nullable component of the cast type, including declared enum types and one-dimensional arrays.
  • New diagnostics: A cast projection requires a result alias, such as SUM(amount)::numeric AS total. and Result column '<alias>' has unsupported cast type <TYPE>.
  • Analyzer tests cover count position, grouped counts with predicate parameters, both cast and alias spellings, enum and array casts, and the rejections; PostgreSQL integration tests execute a generated grouped count and a cast SUM, including the null result when no row matches.
  • docs/queries.md documents both projections, their diagnostics, and the covering tests.

Scope and non-goals

  • The cast operand is not analyzed; it reaches the database as written, and PostgreSQL checks its column references and functions.
  • GROUP BY and HAVING remain unanalyzed and are passed through as written.
  • Expressions without a cast (for example COUNT(column), lower(name), FILTER/OVER forms) and row-type casts stay rejected as unsupported SELECT expressions.
  • A placeholder in a projection, including a cast placeholder such as $1::int AS x, stays rejected.
  • RETURNING, code generation, and the runtime are unchanged.

An aliased COUNT(*) may now stand beside other SELECT items as a non-null
BIGINT column in its own position. A projection written as
<expression>::type AS alias, or CAST(<expression> AS type) AS alias, becomes
a nullable result column of the cast type, including declared enums and
one-dimensional arrays. The cast operand is not analyzed and reaches the
database as written; an unaliased cast and an unmapped cast type are
rejected with their own diagnostics, and a projected placeholder stays
rejected.
@omer-cengel
omer-cengel merged commit 36d4028 into master Oct 3, 2026
6 checks passed
@omer-cengel
omer-cengel deleted the feature/grouped-count-and-cast-projections branch October 3, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant