ERROR: no relation entry for relid 3
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253805psql -h localhost -U postgresBuilt from patchset v1 (message #1), September 16, 2026 at 06:36 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t253805_1 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t253805_1 && git checkout t253805_1Patchset v1 (message #1) is on t253805_1
While fuzzing around the join alias expansion code, I ran into this:
create table t (a int);
select count(*)
from (t t1 full join t t2 using (a)) j,
lateral (select * from t tablesample system (50) repeatable (j.a)) ss;
ERROR: no relation entry for relid 3
This fails all the way back to v14 at least, dates back to the
introduction of TABLESAMPLE.
What happens is that the lateral subquery gets pulled up, and the
sampled relation becomes a lateral RTE of the outer level, with the
join alias Var j.a now in its TABLESAMPLE clause. But
preprocess_expression skips flatten_join_alias_vars for
EXPRKIND_TABLESAMPLE, on the assumption that such clauses can't
contain Vars of the current query level. The alias Var thus never
gets expanded, and results in that error at last.
Apparently that assumption does not always hold. I think we can fix
it the same way lateral function and VALUES RTEs are handled, by
adding an EXPRKIND_TABLESAMPLE_LATERAL and using it for the
TABLESAMPLE clause of a lateral relation RTE, so that only the
non-lateral kind skips the alias expansion. Please see attached.
- Richard
Hi Richard,
I reproduced the error on master, REL_19_STABLE and a June 19beta1
build, and tested v1 on master. The original query works with the
patch, and so do the variants I tried: the alias in the argument
position (tablesample system (j.a)), CROSS JOIN LATERAL and LEFT JOIN
LATERAL, a lateral subquery that itself contains a pulled-up subquery,
a lateral UNION ALL of two sampled scans (appendrel), a second lateral
scan referencing both the first one and j.a, a sublink inside the
REPEATABLE argument, a COALESCE over the alias in the percentage
argument, and the case where the lateral subquery is not pulled up
(LIMIT), which already worked before. EXPLAIN VERBOSE shows the alias
expanded to COALESCE(t1.a, t2.a) in the Sampling line, and a
non-lateral sampled relation still cannot reference the join alias at
all, so keeping the skip for the non-lateral kind is right. make check
passes, and the new regression query fails as expected on unpatched
master.
The fix follows the existing RTFUNC/VALUES/TABLEFUNC lateral pattern,
and TABLESAMPLE was the only RTE expression kind without a lateral
twin, so this looks complete to me.
LGTM.
On Wed, Sep 16, 2026 at 2:24 PM Richard Guo <guofenglinux@gmail.com> wrote:
While fuzzing around the join alias expansion code, I ran into this:
create table t (a int);
select count(*)
from (t t1 full join t t2 using (a)) j,
lateral (select * from t tablesample system (50) repeatable (j.a)) ss;
ERROR: no relation entry for relid 3This fails all the way back to v14 at least, dates back to the
introduction of TABLESAMPLE.What happens is that the lateral subquery gets pulled up, and the
sampled relation becomes a lateral RTE of the outer level, with the
join alias Var j.a now in its TABLESAMPLE clause. But
preprocess_expression skips flatten_join_alias_vars for
EXPRKIND_TABLESAMPLE, on the assumption that such clauses can't
contain Vars of the current query level. The alias Var thus never
gets expanded, and results in that error at last.Apparently that assumption does not always hold. I think we can fix
it the same way lateral function and VALUES RTEs are handled, by
adding an EXPRKIND_TABLESAMPLE_LATERAL and using it for the
TABLESAMPLE clause of a lateral relation RTE, so that only the
non-lateral kind skips the alias expansion. Please see attached.- Richard
--
Regards,
Ewan Young
Hi,
On Wed, 16 Sept 2026 at 11:54, Richard Guo <guofenglinux@gmail.com> wrote:
While fuzzing around the join alias expansion code, I ran into this:
create table t (a int);
select count(*)
from (t t1 full join t t2 using (a)) j,
lateral (select * from t tablesample system (50) repeatable (j.a)) ss;
ERROR: no relation entry for relid 3This fails all the way back to v14 at least, dates back to the
introduction of TABLESAMPLE.What happens is that the lateral subquery gets pulled up, and the
sampled relation becomes a lateral RTE of the outer level, with the
join alias Var j.a now in its TABLESAMPLE clause. But
preprocess_expression skips flatten_join_alias_vars for
EXPRKIND_TABLESAMPLE, on the assumption that such clauses can't
contain Vars of the current query level. The alias Var thus never
gets expanded, and results in that error at last.Apparently that assumption does not always hold. I think we can fix
it the same way lateral function and VALUES RTEs are handled, by
adding an EXPRKIND_TABLESAMPLE_LATERAL and using it for the
TABLESAMPLE clause of a lateral relation RTE, so that only the
non-lateral kind skips the alias expansion. Please see attached.
Thanks for the patch! It looks good to me.
Though is the EXPLAIN test added necessary? Since the execution
query already fails without the fix, maybe we can get rid of the EXPLAIN
portion?
Regards,
Ayush