| From: | Tender Wang <tndrwang(at)gmail(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
| Cc: | Alexander Kuzmenkov <akuzmenkov(at)tigerdata(dot)com> |
| Subject: | Re: assertion failure with unique index + partitioning + join |
| Date: | 2026-06-16 01:58:07 |
| Message-ID: | CAHewXNn6ENbO2mYqFd0xwQBFytseyghQkq5Kbe61ijaYR69qsw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Alexander Kuzmenkov <akuzmenkov(at)tigerdata(dot)com> 于2026年6月15日周一 23:39写道:
>
> Hi hackers,
>
> While I was running some random testing on the TimescaleDB extension, I noticed that I can easily hit an assertion failure in plain Postgres REL_18_STABLE. I haven't analyzed it at all, but thought I should report this:
>
> CREATE TABLE t (a bool UNIQUE) PARTITION BY LIST (a);
> CREATE TABLE p PARTITION OF t DEFAULT;
> SELECT
> FROM (
> SELECT *
> FROM t
> LEFT JOIN t r USING (a)
> )
> WHERE a
> GROUP BY ();
>
>
> TRAP: failed Assert("bms_is_member(i, root->outer_join_rels)"), File: "../pg/src/backend/optimizer/path/equivclass.c", Line: 3631, PID: 1813021
>
I can reproduce this issue on HEAD.
The root->outer_join_rels is empty, and the i is 3(rel: t r).
The left join can be removed in remove_useless_joins(), in which
root->outer_join_rels is changed to be empty.
But the from->qual in this case has already been distributed to its rel.
(gdb) pgprint brel->baserestrictinfo
RestrictInfo [is_pushed_down=true can_join=false pseudoconstant=false
has_clone=false is_clone=false leakproof=false
has_volatile=VOLATILITY_UNKNOWN security_level=0
num_base_rels=1 rinfo_serial=1 eval_cost={startup = -1,
per_tuple = 0} norm_selec=-1 outer_selec=-1 outer_is_left=false
hashjoinoperator=0 left_bucketsize=-1
right_bucketsize=-1 left_mcvfreq=-1 right_mcvfreq=-1
left_hasheqoperator=0 right_hasheqoperator=0]
[clause]
PlaceHolderVar [phid=1 phlevelsup=0]
[phexpr] Var [varno=2 varattno=1 vartype=16
varreturningtype=VAR_RETURNING_DEFAULT varnosyn=2 varattnosyn=1]
[phrels] Bitmapset [4 3 2]
[clause_relids] Bitmapset [2]
[required_relids] Bitmapset [2]
It was distributed to (rel:2, table t), but I think "[phrels]
Bitmapset [4 3 2]" is incorrect. After leftjoin is removed, we no
longer need rel=4 (outerjoin) and rel=3 (t r).
But the qual has already been distributed to the (rel: 2) when
deconstruct_jointree (). Then the qual is inherited by its child(table
p)
It seems that we have no logic to process this distributed
restrictinfo in remove_useless_joins().
I need to dig deeper to find out how to fix it.
--
Thanks,
Tender Wang
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Ewan Young | 2026-06-16 02:02:15 | Re: REPACK CONCURRENTLY fails on tables with generated columns |
| Previous Message | Peter Travers | 2026-06-16 01:49:03 | Re: [PATCH] proposal to surface index used by replica identity |