| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | alpkeles99(at)gmail(dot)com |
| Subject: | BUG #19784: "no relation entry for relid 1" when costing = ANY (<array expr over max(col)>) in a MinMaxAggPath |
| Date: | 2026-10-21 21:03:30 |
| Message-ID: | 19784-93f76236decd0656@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19784
Logged by: Alperen Keles
Email address: alpkeles99(at)gmail(dot)com
PostgreSQL version: 18.6
Operating system: Ubuntu 24.04 x86_64 (also macOS 26 arm64)
Description:
Hello,
A query whose aggregates are all min()/max() over an indexed column
fails in the planner with an internal error when its target list or
HAVING contains "x op ANY/ALL (array)" where the array is an expression
over the aggregate (anything but a constant or a plain ARRAY[...]):
CREATE TABLE rt (c0 int4);
CREATE INDEX ON rt (c0);
SELECT 1 = ANY (array_append(ARRAY[2], max(c0))) FROM rt;
ERROR: no relation entry for relid 1
SELECT max(c0) FROM rt HAVING 1 = ANY (array_append(ARRAY[2], max(c0)));
ERROR: no relation entry for relid 1
The same happens when the aggregate is in a FROM subquery (or a view,
an inlined CTE, a LATERAL subquery) and the condition is in the outer
WHERE, because the qual is pushed down into the subquery's HAVING:
SELECT * FROM (SELECT max(c0) FROM rt) AS s(c0)
WHERE 1 = ANY (array_append(ARRAY[2], s.c0));
ERROR: no relation entry for relid 1
It also fails with min(), with ALL, < ANY, <> ALL, with array_prepend,
array_cat, array_remove, ||, string_to_array or a CASE yielding an
array, with max() of an indexed array column used directly (CREATE
TABLE at (a int4[]); CREATE INDEX ON at (a); SELECT 1 = ANY (max(a))
FROM at;), with a primary key instead of a plain index, with a text
column, and with or without data and ANALYZE. It does not fail without the
index, with ARRAY[max(c0), 2]
or an IN list, when another aggregate such as count(*) is present, or
with a MATERIALIZED CTE: then the min/max optimization is not used, the
array length is known without statistics, or the condition does not
reach the aggregate query.
Reproduced on 18.6 (REL_18_STABLE dfbc1507cdb), 19rc1 (REL_19_STABLE
1212d5d33b1) and master a261fc2b722, Ubuntu 24.04 x86_64,
--enable-cassert; also on 18.6 and master on macOS arm64. 14.24
(REL_14_STABLE 14904052e65) returns results. The first failing commit
is 9391f7152 ("Teach estimate_array_length() to use statistics where
available"); its parent works.
As far as I can tell: grouping_planner() calls
preprocess_minmax_aggregates() before query_planner(). When the
optimization applies, planagg costs the target list
(create_pathtarget -> set_pathtarget_cost_width) and the HAVING quals
(create_minmaxagg_path -> cost_qual_eval) with the main root. For a
ScalarArrayOpExpr whose array is not a Const or ArrayExpr,
estimate_array_length() calls examine_variable(); the expression
contains the Var c0 of relation 1 inside the Aggref, so
examine_variable() calls find_base_rel(root, 1), but no RelOptInfos
exist at that point yet. This looks like the same problem as bug
#19037 (cost_qual_eval from cost_subplan before the RelOptInfos exist,
fixed in aba8f61c3 for SubPlans only), at another call site.
Found with a query fuzzer.
Regards,
Alperen Keles
| From | Date | Subject | |
|---|---|---|---|
| Next Message | PG Bug reporting form | 2026-10-21 22:11:35 | BUG #19785: Sorted GROUPING SETS return a grouping column's value in a set that leaves it out |
| Previous Message | PG Bug reporting form | 2026-10-21 19:59:51 | BUG #19783: Sorted GROUPING SETS return a grouping column's value in a set that leaves it out |