Skip to content

ClickHouse: format aggregate functions with combinators as function calls (countMerge, sumIf, ...) - #988

Closed
MunMunMiao wants to merge 1 commit into
sql-formatter-org:masterfrom
MunMunMiao:clickhouse-aggregate-combinators
Closed

MunMunMiao wants to merge 1 commit into
sql-formatter-org:masterfrom
MunMunMiao:clickhouse-aggregate-combinators

Conversation

@MunMunMiao

@MunMunMiao MunMunMiao commented Oct 14, 2026 •

Copy link
Copy Markdown

Problem

In the ClickHouse dialect, the name of an aggregate function with a combinator appended (sumIf, countMerge, uniqExactIfState, ...) is not in the list of functions, because the list comes from system.functions and ClickHouse builds these names from the aggregate function and the combinators. They are treated as plain identifiers, so there is a space before the parenthesis, unlike sum(x):

SELECT sumIf(x, y > 1), countMerge(s), uniqExactIfState(id), groupArrayArray(a) FROM t

Before (15.9.0, language: 'clickhouse'):

SELECT
  sumIf (x, y > 1),
  countMerge (s),
  uniqExactIfState (id),
  groupArrayArray (a)
FROM
  t

After:

SELECT
  sumIf(x, y > 1),
  countMerge(s),
  uniqExactIfState(id),
  groupArrayArray(a)
FROM
  t

Combinators are very common in materialized views and in queries on AggregatingMergeTree tables (...State when writing, ...Merge when reading).

Change

postProcess in the ClickHouse dialect already turns SET into a function name when a parenthesis follows. This does the same for an identifier that

  • is directly followed by a parenthesis, and
  • is a name from the function list with one or more combinators appended.

The combinators are the ones in the documentation. Requiring the base name to be a known function keeps the change narrow: an identifier like userState(x) is formatted as before.

Not in this PR

A parametric aggregate call quantile(0.9)(x) is still formatted as quantile(0.9) (x), also for functions that are in the list. That comes from how a second parenthesis after a function call is parsed, not from the dialect, so I left it out.

Tests

Added a test for the new names. pnpm exec jest passes for all dialects (5886 passed, 1 skipped), and tsc --noEmit, prettier --check and eslint are clean.

Fixes #990.


This change was prepared with Claude Code (an AI coding assistant) and checked by running the full test suite locally.

ClickHouse builds names like `sumIf`, `countMerge` or `uniqExactIfState`
from an aggregate function and combinators, so they are not in the list
of functions (it comes from `system.functions`). They were treated as
identifiers and printed with a space before the parenthesis:
`countMerge (x)`. Treat an identifier that is a known aggregate function
with combinators appended, and is followed by a parenthesis, as a function
name.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Reclassified functions do not honor the standard uppercase functionCase option.

2 open findings
What changed in this PR

Adds recognition of ClickHouse aggregate-function combinators so calls format without unwanted spaces.

Changes:

  • Detects known functions with appended aggregate combinators.
  • Adds representative combinator-formatting coverage.
File Description
src/​languages/​clickhouse/​clickhouse.formatter.ts Recognizes combinator-based aggregate calls.
test/​clickhouse.test.ts Tests representative combinator names.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

nextToken.type === TokenType.OPEN_PAREN &&
isAggregateWithCombinators(token.text)
) {
return { ...token, type: TokenType.RESERVED_FUNCTION_NAME };
Comment thread test/clickhouse.test.ts
});

// https://clickhouse.com/docs/sql-reference/window-functions
describe('Aggregate function combinators', () => {
@MunMunMiao

Copy link
Copy Markdown
Author

Closing for now: I'm going to handle the formatting on my side instead. Thanks for the library.

@MunMunMiao MunMunMiao closed this Oct 14, 2026
@MunMunMiao
MunMunMiao deleted the clickhouse-aggregate-combinators branch October 14, 2026 04:17
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.

[FORMATTING] ClickHouse: aggregate functions with combinators (countMerge, sumIf, ...) get a space before the parenthesis

2 participants