From: | Kouhei Kaigai <kaigai(at)ak(dot)jp(dot)nec(dot)com> |
---|---|
To: | Shigeru Hanada <shigeru(dot)hanada(at)gmail(dot)com> |
Cc: | Robert Haas <robertmhaas(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Join push-down support for foreign tables |
Date: | 2015-03-05 01:27:15 |
Message-ID: | 9A28C8860F777E439AA12E8AEA7694F8010BBD8F@BPXM15GP.gisp.nec.co.jp |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
> Here is v4 patch of Join push-down support for foreign tables. This
> patch requires Custom/Foreign join patch v7 posted by Kaigai-san.
>
Thanks for your efforts,
> In this version I added check about query type which gives up pushing
> down joins when the join is a part of an underlying query of
> UPDATE/DELETE.
>
> As of now postgres_fdw builds a proper remote query but it can't bring
> ctid value up to postgresExecForeignUpdate()...
>
The "ctid" reference shall exist as an usual column reference in
the target-list of join-rel. It is not origin of the problem.
See my investigation below. I guess special treatment on whole-row-
reference is problematic, rather than ctid.
> How to reproduce the error, please execute query below after running
> attached init_fdw.sql for building test environment. Note that the
> script drops "user1", and creates database "fdw" and "pgbench".
>
> fdw=# explain (verbose) update pgbench_branches b set filler = 'foo'
> from pgbench_tellers t where t.bid = b.bid and t.tid < 10;
>
> QUERY
> PLAN
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------------
> ----------------------------------------------------------------------------
> -----------------------------------
> Update on public.pgbench_branches b (cost=100.00..100.67 rows=67 width=390)
> Remote SQL: UPDATE public.pgbench_branches SET filler = $2 WHERE ctid = $1
> -> Foreign Scan (cost=100.00..100.67 rows=67 width=390)
> Output: b.bid, b.bbalance, 'foo
>
> '::character(88), b.ctid, *
> Remote SQL: SELECT r.a_0, r.a_1, r.a_2, l FROM (SELECT tid,
> bid, tbalance, filler FROM public.pgbench_tellers WHERE ((tid < 10)))
> l (a_0, a_1) INNER JOIN (SELECT b
> id, bbalance, NULL, ctid FROM public.pgbench_branches FOR UPDATE) r
> (a_0, a_1, a_2, a_3) ON ((r.a_0 = l.a_1))
> (5 rows)
> fdw=# explain (analyze, verbose) update pgbench_branches b set filler
> = 'foo' from pgbench_tellers t where t.bid = b.bid and t.tid < 10;
> ERROR: ctid is NULL
>
It seems to me the left relation has smaller number of alias definitions
than required. The left SELECT statement has 4 target-entries, however,
only a_0 and a_1 are defined.
The logic to assign aliases of relation/column might be problematic.
Because deparseColumnAliases() add aliases for each target-entries of
underlying SELECT statement, but skips whole-row0-reference.
On the other hands, postgres_fdw takes special treatment on whole-
row-reference. Once a whole-row-reference is used, postgres_fdw
put all the non-system columns on the target-list of remote SELECT
statement.
Thus, it makes mismatch between baserel->targetlist and generated
aliases.
I think we have two options:
(1) Stop special treatment for whole-row-reference, even if it is
simple foreign-scan (which does not involve join).
(2) Add a new routine to reconstruct whole-row-reference of
a particular relation from the target-entries of joined relations.
My preference is (2). It can keep the code simple, and I doubt
whether network traffic optimization actually has advantage towards
disadvantage of local tuple reconstruction (which consumes additional
CPU cycles).
Does it make sense for you?
--
NEC OSS Promotion Center / PG-Strom Project
KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>
From | Date | Subject | |
---|---|---|---|
Next Message | Josh Berkus | 2015-03-05 01:56:25 | Re: MD5 authentication needs help |
Previous Message | Peter Geoghegan | 2015-03-05 01:18:17 | INSERT ... ON CONFLICT IGNORE (and UPDATE) 3.0 |