| From: | Alexander Pyhalov <a(dot)pyhalov(at)postgrespro(dot)ru> |
|---|---|
| To: | Alexander Korotkov <aekorotkov(at)gmail(dot)com> |
| Cc: | solaimurugan vellaipandiyan <drsolaimurugan(dot)v(at)gmail(dot)com>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>, g(dot)kashkin(at)postgrespro(dot)ru, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Function scan FDW pushdown |
| Date: | 2026-05-20 10:17:04 |
| Message-ID: | 214e7cb76a9f142a08246660a649ca0b@postgrespro.ru |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Alexander Korotkov писал(а) 2026-05-19 21:21:
> Good evening!
>
> On Tue, May 19, 2026 at 6:25 PM Alexander Pyhalov
> <a(dot)pyhalov(at)postgrespro(dot)ru> wrote:
>>
>> Found one more issue in whole row var deparsing. It can appear on a
>> nullable outer side, and we should use the same logic as when
>> deparsing
>> table column reference. Otherwise we get records from nulls instead of
>> nulls (for example, "(NULL, NULL)" instead of NULL).
>
>
> Good catch, accepted.
>
Hi.
I've found another issue. The fact that in the new versions of the patch
RTE RelOptInfo misses fdw_private seems to be unfortunate. For example,
in the last version we haven't thought about classifying
baserestrictinfo. And if we do, we should pass fdw_private down to
foreign_expr_walker. Perhaps, we could attach it to RTE_FUNCTION rel
prior to calling classifyConditions(), but should we later set it back
to NULL? Another problem comes if we try to handle joins, which can
crearte subqueries (like INNER/OUTER UNIQUE). In this case we should
somehow cook fpinfo for get_relation_column_alias_ids(). Attaching patch
which tries to handle baserestrictinfos by passing fpinfo down to
foreign_expr_walker().
One more interesting example (included in the patch) is
EXPLAIN (VERBOSE, COSTS OFF)
WITH s AS MATERIALIZED (SELECT r1.* FROM remote_tbl r1
JOIN LATERAL
(SELECT r2.a FROM remote_tbl r2, f(r1.a) LIMIT 1) s
ON true)
SELECT * FROM s ORDER BY 1;
We get the following plan:
Sort
Output: s.a, s.b
Sort Key: s.a
CTE s
-> Nested Loop
Output: r1.a, r1.b
-> Foreign Scan on public.remote_tbl r1
Output: r1.a, r1.b
Remote SQL: SELECT a, b FROM public.base_tbl_fn
-> Foreign Scan
Output: NULL::integer
Relations: (public.remote_tbl r2) INNER JOIN (Function
f)
Remote SQL: SELECT NULL FROM (public.base_tbl_fn r1
INNER JOIN public.f($1::integer) f2(c1) ON (TRUE)) LIMIT 1::bigint
-> CTE Scan on s
Output: s.a, s.b
Here you can see that we use parameter in function argument. Don't know
if it's a real problem, but at least looks suspicious. In v3 patch used
contain_param_walker() in is_nonrel_relinfo_ok() (which mutated to
function_rte_pushdown_ok()) to avoid such plans.
One minor issue I've noticed is in function_rte_pushdown_ok():
+ if (rel->rtekind != RTE_FUNCTION)
+ return false;
+ rte = planner_rt_fetch(rel->relid, root);
+ if (rte->rtekind != RTE_FUNCTION)
+ return false;
Is the second rtekind check necessary?
--
Best regards,
Alexander Pyhalov,
Postgres Professional
| Attachment | Content-Type | Size |
|---|---|---|
| v9-0001-postgres_fdw-push-down-FUNCTION-RTE-into-foreign-joi.patch | text/x-diff | 72.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Rafia Sabih | 2026-05-20 10:40:11 | Re: Bypassing cursors in postgres_fdw to enable parallel plans |
| Previous Message | Japin Li | 2026-05-20 10:00:56 | Re: Add pg_get_publication_ddl function |