mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix join alias expansion in lateral TABLESAMPLE clauses
preprocess_expression skips flatten_join_alias_vars for TABLESAMPLE clauses, on the assumption that they cannot contain Vars of the current query level. That's not true once a LATERAL subquery containing a sampled relation has been pulled up: the relation's TABLESAMPLE clause then becomes a lateral reference of this level, and if it referred to a join alias Var, that Var is left unexpanded. extract_lateral_references then pulls the join alias Var out as a lateral reference and fails with "no relation entry for relid N". To fix, treat such clauses like lateral function and VALUES RTEs: introduce EXPRKIND_TABLESAMPLE_LATERAL, used for the TABLESAMPLE clause of a lateral relation RTE, and keep skipping the alias expansion only for the non-lateral kind. Back-patch to all supported branches, as this dates back to the introduction of TABLESAMPLE. Author: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Ewan Young <kdbase.hack@gmail.com> Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com> Discussion: https://postgr.es/m/CAMbWs4834TwOtyyycyvja3MuOBkfpXy3dFAL0zt_vcM1KtqV-Q@mail.gmail.com Backpatch-through: 14
This commit is contained in:
@@ -89,9 +89,10 @@ create_upper_paths_hook_type create_upper_paths_hook = NULL;
|
||||
#define EXPRKIND_APPINFO 7
|
||||
#define EXPRKIND_PHV 8
|
||||
#define EXPRKIND_TABLESAMPLE 9
|
||||
#define EXPRKIND_ARBITER_ELEM 10
|
||||
#define EXPRKIND_TABLEFUNC 11
|
||||
#define EXPRKIND_TABLEFUNC_LATERAL 12
|
||||
#define EXPRKIND_TABLESAMPLE_LATERAL 10
|
||||
#define EXPRKIND_ARBITER_ELEM 11
|
||||
#define EXPRKIND_TABLEFUNC 12
|
||||
#define EXPRKIND_TABLEFUNC_LATERAL 13
|
||||
|
||||
/* Passthrough data for standard_qp_callback */
|
||||
typedef struct
|
||||
@@ -887,10 +888,15 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
|
||||
if (rte->rtekind == RTE_RELATION)
|
||||
{
|
||||
if (rte->tablesample)
|
||||
{
|
||||
/* Preprocess the tablesample expression(s) fully */
|
||||
kind = rte->lateral ? EXPRKIND_TABLESAMPLE_LATERAL :
|
||||
EXPRKIND_TABLESAMPLE;
|
||||
rte->tablesample = (TableSampleClause *)
|
||||
preprocess_expression(root,
|
||||
(Node *) rte->tablesample,
|
||||
EXPRKIND_TABLESAMPLE);
|
||||
kind);
|
||||
}
|
||||
}
|
||||
else if (rte->rtekind == RTE_SUBQUERY)
|
||||
{
|
||||
|
||||
@@ -279,6 +279,38 @@ select pct, count(unique1) from
|
||||
100 | 10000
|
||||
(1 row)
|
||||
|
||||
-- check that a join alias Var in a pulled-up LATERAL subquery's TABLESAMPLE
|
||||
-- clause gets flattened
|
||||
explain (costs off)
|
||||
select pct, count(unique1) from
|
||||
((values (0)) v(pct) full join (values (100)) w(pct) using (pct)),
|
||||
lateral (select * from tenk1 tablesample bernoulli (pct)) ss
|
||||
group by pct order by pct;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------
|
||||
GroupAggregate
|
||||
Group Key: (COALESCE((0), (100)))
|
||||
-> Sort
|
||||
Sort Key: (COALESCE((0), (100)))
|
||||
-> Nested Loop
|
||||
-> Hash Full Join
|
||||
Hash Cond: ((0) = (100))
|
||||
-> Result
|
||||
-> Hash
|
||||
-> Result
|
||||
-> Sample Scan on tenk1
|
||||
Sampling: bernoulli (COALESCE((0), (100)))
|
||||
(12 rows)
|
||||
|
||||
select pct, count(unique1) from
|
||||
((values (0)) v(pct) full join (values (100)) w(pct) using (pct)),
|
||||
lateral (select * from tenk1 tablesample bernoulli (pct)) ss
|
||||
group by pct order by pct;
|
||||
pct | count
|
||||
-----+-------
|
||||
100 | 10000
|
||||
(1 row)
|
||||
|
||||
-- errors
|
||||
SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1);
|
||||
ERROR: tablesample method foobar does not exist
|
||||
|
||||
@@ -82,6 +82,18 @@ select pct, count(unique1) from
|
||||
lateral (select * from tenk1 tablesample system (pct)) ss
|
||||
group by pct;
|
||||
|
||||
-- check that a join alias Var in a pulled-up LATERAL subquery's TABLESAMPLE
|
||||
-- clause gets flattened
|
||||
explain (costs off)
|
||||
select pct, count(unique1) from
|
||||
((values (0)) v(pct) full join (values (100)) w(pct) using (pct)),
|
||||
lateral (select * from tenk1 tablesample bernoulli (pct)) ss
|
||||
group by pct order by pct;
|
||||
select pct, count(unique1) from
|
||||
((values (0)) v(pct) full join (values (100)) w(pct) using (pct)),
|
||||
lateral (select * from tenk1 tablesample bernoulli (pct)) ss
|
||||
group by pct order by pct;
|
||||
|
||||
-- errors
|
||||
SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user