RE: Query ID Calculation Fix for DISTINCT / ORDER BY and LIMIT / OFFSET

Ivan Bykov <i.bykov@modernsys.ru>

From: Bykov Ivan <i.bykov@modernsys.ru>
To: "pgsql-hackers@postgresql.org" <pgsql-hackers@postgresql.org>
Date: 2025-03-06T14:32:41Z
Lists: pgsql-hackers

Attachments

Hello!

Last time, I forgot to attach the patches.
The problem still persists in the 17.3 release.

Solution One
============
The simplest way to fix the problem is to place the scalar field used in the query ID calculation
between similar subnodes.
A patch for this solution is attached below (0001-Query-ID-Calculation-Fix-Variant-A.patch).

Solution Two
============
Alternatively, we can change the hash sum when we encounter an empty node.
This approach may impact performance but will protect us from such errors in the future.
A patch for this solution is attached below (0001-Query-ID-Calculation-Fix-Variant-B.patch).


======
SELECT version();
                                             version
-------------------------------------------------------------------------------------------------
PostgreSQL 17.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit

SET compute_query_id = on;

/* LIMIT / OFFSET */
EXPLAIN (VERBOSE) SELECT "oid" FROM pg_class LIMIT 1;

                                 QUERY PLAN
----------------------------------------------------------------------------
Limit  (cost=0.00..0.04 rows=1 width=4)
   Output: oid
   ->  Seq Scan on pg_catalog.pg_class  (cost=0.00..18.15 rows=415 width=4)
         Output: oid
Query Identifier: 5185884322440896420

EXPLAIN (VERBOSE) SELECT "oid" FROM pg_class OFFSET 1;
                                 QUERY PLAN
----------------------------------------------------------------------------
Limit  (cost=0.04..18.15 rows=414 width=4)
   Output: oid
   ->  Seq Scan on pg_catalog.pg_class  (cost=0.00..18.15 rows=415 width=4)
         Output: oid
Query Identifier: 5185884322440896420

/* DISTINCT / ORDER BY */
EXPLAIN (VERBOSE) SELECT DISTINCT "oid" FROM pg_class;

                                                 QUERY PLAN
------------------------------------------------------------------------------------------------------------
Unique  (cost=0.27..23.54 rows=415 width=4)
   Output: oid
   ->  Index Only Scan using pg_class_oid_index on pg_catalog.pg_class  (cost=0.27..22.50 rows=415 width=4)
         Output: oid
Query Identifier: 751948508603549510

EXPLAIN (VERBOSE) SELECT "oid" FROM pg_class ORDER BY "oid";

                                              QUERY PLAN
------------------------------------------------------------------------------------------------------
Index Only Scan using pg_class_oid_index on pg_catalog.pg_class  (cost=0.27..22.50 rows=415 width=4)
   Output: oid
Query Identifier: 751948508603549510

Commits

  1. Optimize Query jumble