BUG #19751: MIN aggregate + FETCH FIRST 1 ROW WITH TIES causes false 21000 error when index scan is forced - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #19751: MIN aggregate + FETCH FIRST 1 ROW WITH TIES causes false 21000 error when index scan is forced
Date
Msg-id 19751-db95b8241f0e33d9@postgresql.org
Whole thread
Responses Re: BUG #19751: MIN aggregate + FETCH FIRST 1 ROW WITH TIES causes false 21000 error when index scan is forced
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      19751
Logged by:          N J
Email address:      1482694023@qq.com
PostgreSQL version: 18.6
Operating system:   Windows 11 64-bit
Description:

Environment:
PostgreSQL: [fill in your exact version]
OS: Windows 11 64-bit

Steps to reproduce:

1. Create test table and insert data:
CREATE TEMP TABLE readings (
    region_id integer NOT NULL,
    reading integer NOT NULL
);
INSERT INTO readings (region_id, reading) VALUES
    (2, 7),
    (2, 1);

2. Create index and collect statistics:
CREATE INDEX ON readings (region_id, reading);
ANALYZE readings;

3. Force index scan and execute the query:
SET enable_seqscan = off;

SELECT MIN(reading) AS minimum
FROM (
    SELECT reading
    FROM readings
    WHERE region_id = 2
) AS scoped
ORDER BY minimum
FETCH FIRST 1 ROW WITH TIES;

Observed result:
ERROR:  more than one row returned by a subquery used as an expression
SQL state: 21000

Expected result:
 minimum
---------
       1
(1 row)

Bug analysis:
This is a valid standard SQL query. The subquery is only used as a derived
table in the FROM clause, there is no scalar subquery in the statement. The
21000 cardinality error should never be raised here.

The error only triggers under these conditions:
- Sequential scan is disabled, so the optimizer uses an index scan to
optimize the MIN() aggregate
- The query includes FETCH FIRST 1 ROW WITH TIES
- The inner derived table returns multiple rows

It appears that when the optimizer combines the index-optimized MIN() path
with the WITH TIES logic, it incorrectly generates an execution plan that
treats the internal index scan subplan as a scalar subquery, resulting in a
spurious error when the subplan returns multiple rows. This is an optimizer
correctness bug.





pgsql-bugs by date:

Previous
From: Andrey Rachitskiy
Date:
Subject: Re: BUG #19732: first_value/last_value/nth_value return NULL with EXCLUDE TIES when the current row is outside its f
Next
From: Andrew Dunstan
Date:
Subject: Re: Issue Installing PostGIS via Stack Builder on MacBook (Apple Silicon / ARM64) – Application Buffers/Freezes