Re: Have the planner convert COUNT(1) / COUNT(not_null_col) to COUNT(*)

From: David Rowley <dgrowleyml(at)gmail(dot)com>
To: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>
Cc: PostgreSQL Developers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Have the planner convert COUNT(1) / COUNT(not_null_col) to COUNT(*)
Date: 2025-10-30 04:20:55
Message-ID: CAApHDvppFVDdjpYrs=pwgCnp-jv-tneQyfu8rWM8ymHcuJOJYw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, 30 Oct 2025 at 16:40, Corey Huinker <corey(dot)huinker(at)gmail(dot)com> wrote:
> I'm in favor of the COUNT(NULL) optimization as well, as one of my favorite programming tropes is "There is nothing faster than nothing".

I think it would be much more interesting to do that if it could be
detected in cases like:

SELECT COUNT(col) FROM table WHERE col IS NULL;

which might be a more realistic thing if the query without the WHERE
clause was part of a VIEW. However, we don't currently have any
infrastructure to detect when a column *is* NULL. There's only the
opposite with expr_is_nonnullable() or var_is_nonnullable().

This does make me wonder if constant-folding is too early to do this
transformation, as it currently happens before
add_base_clause_to_rel() therefore we can't really transform cases
such as:

SELECT count(nullable_col) FROM t WHERE nullable_col IS NOT NULL;

There might be a better spot in planning to do this at a point after
add_base_clause_to_rel() is called. It just has to happen before the
search for Aggrefs with the same aggtransfn in preprocess_aggref() as
it's too late to swap aggregate functions around when they've already
been grouped together with other aggs that can share the same
transition state. I'm just subtly aware about Tom's complaints with
the restriction_is_always_true() code as he thought it should go into
the constant folding code, where it mostly now is, per Richard's work
to put it there.

> The check seems lightweight enough to me. Applies clean and tests pass. Test coverage seems to cover all the cases.

Thanks for having a look and testing.

I've attached a very slightly revised version of the patch. I became
aware of a function named get_func_support(), which can be used rather
than fetching the pg_proc tuple from SysCache, which I was doing in
v1. No other changes.

David

Attachment Content-Type Size
v2-0001-Have-the-planner-replace-COUNT-ANY-with-COUNT-whe.patch application/octet-stream 22.6 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2025-10-30 05:01:07 Re: tuple radix sort
Previous Message Bertrand Drouvot 2025-10-30 04:18:26 Re: Question about InvalidatePossiblyObsoleteSlot()