Re: [v9.3] writable foreign tables

From: Kohei KaiGai <kaigai(at)kaigai(dot)gr(dot)jp>
To: Albe Laurenz <laurenz(dot)albe(at)wien(dot)gv(dot)at>
Cc: Atri Sharma <atri(dot)jiit(at)gmail(dot)com>, "Alexander Korotkov *EXTERN*" <aekorotkov(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Robert Haas <robertmhaas(at)gmail(dot)com>, PgHacker <pgsql-hackers(at)postgresql(dot)org>, Shigeru Hanada <shigeru(dot)hanada(at)gmail(dot)com>
Subject: Re: [v9.3] writable foreign tables
Date: 2012-12-03 12:39:21
Message-ID: CADyhKSVrNV_c5rrXym776wTxi8Ff4NA-MNQ9R3A3WpRekMrJiA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

The attached patch is revised version.

One most difference from the previous version is, it constructed
PoC features on Hanada-san's latest postgres-fdw.v5.patch.
Yesh, it looks to me working fine on RDBMS backend also.

Even though the filename of this patch contains "poc" phrase,
I think it may be time to consider adoption of the core regarding
to the interface portion.
(Of course, postgres_fdw is still works in progress.)

Here is a few operation examples.

postgres=# CREATE FOREIGN TABLE tbl (a int, b text, c date) SERVER loopback;
CREATE FOREIGN TABLE
postgres=# SELECT * FROM tbl;
a | b | c
---+-----+------------
1 | aaa | 2012-12-01
2 | bbb | 2012-12-02
3 | ccc | 2012-12-03
4 | ddd | 2012-12-04
5 | eee | 2012-12-05
6 | fff | 2012-12-06
(6 rows)

postgres=# UPDATE tbl SET b = b || b WHERE a % 2 = 1;
UPDATE 3
postgres=# SELECT * FROM tbl ORDER BY a;
a | b | c
---+--------+------------
1 | aaaaaa | 2012-12-01
2 | bbb | 2012-12-02
3 | cccccc | 2012-12-03
4 | ddd | 2012-12-04
5 | eeeeee | 2012-12-05
6 | fff | 2012-12-06
(6 rows)

postgres=# INSERT INTO tbl VALUES (7,'ggg'),(8,'hhh');
INSERT 0 2
postgres=# SELECT * FROM tbl ORDER BY a;
a | b | c
---+--------+------------
1 | aaaaaa | 2012-12-01
2 | bbb | 2012-12-02
3 | cccccc | 2012-12-03
4 | ddd | 2012-12-04
5 | eeeeee | 2012-12-05
6 | fff | 2012-12-06
7 | ggg |
8 | hhh |
(8 rows)

postgres=# DELETE FROM tbl WHERE a % 2 = 0;
DELETE 4
postgres=# SELECT * FROM tbl ORDER BY a;
a | b | c
---+--------+------------
1 | aaaaaa | 2012-12-01
3 | cccccc | 2012-12-03
5 | eeeeee | 2012-12-05
7 | ggg |
(4 rows)

Even though it still has restriction of transaction control on remote side,
I believe Hanada-san will provide more graceful implementation next to
the first read-only version getting committed.

So, let's back to the main topic of this patch.
According to the upthread discussion, I renamed the interface to inform
expected width of result set as follows:

+typedef AttrNumber (*GetForeignRelWidth_function) (PlannerInfo *root,
+ RelOptInfo *baserel,
+ Relation foreignrel,
+ bool inhparent,
+ List *targetList);

It informs the core how many slots for regular and pseudo columns shall
be acquired. If it is identical with number of attributed in foreign table
definition, it also means this scan does not use any pseudo columns.
A typical use case of pseudo column is "rowid" to move an identifier of
remote row from scan stage to modify stage. It is responsibility of FDW
driver to ensure "rowid" has uniqueness on the remote side; my
enhancement on postgres_fdw uses ctid.

get_pseudo_rowid_column() is a utility function that picks up an attribute
number of pseudo "rowid" column if query rewriter injected on previous
stage. If FDW does not support any other pseudo column features, the
value to be returned is just return-value of this function.

Other relevant APIs are as follows:

+typedef List *(*PlanForeignModify_function) (PlannerInfo *root,
+ ModifyTable *plan,
+ Index resultRelation,
+ Plan *subplan);
+
I newly added this handler on construction of ModifyTable structure.
Because INSERT command does not have scan stage directly connected
with table modification, FDW driver has no chance to construct its private
stuff relevant to table modification. (In case postgres_fdw, it constructs
the second query to modify remote table with/without given ctid.)
Its returned List * value is moved to BeginForeignModify handler as
third argument.

+typedef void (*BeginForeignModify_function) (ModifyTableState *mtstate,
+ ResultRelInfo *resultRelInfo,
+ List *fdw_private,
+ Plan *subplan,
+ int eflags);
I adjusted some arguments to reference fdw_private being constructed
on query plan stage. The role of this handler is not changed. FDW driver
should have all the initialization stuff on this handler, like we are doing at
BeginForeignScan.

+typedef int (*ExecForeignInsert_function) (ResultRelInfo *resultRelInfo,
+ HeapTuple tuple);
+typedef int (*ExecForeignDelete_function) (ResultRelInfo *resultRelInfo,
+ Datum rowid);
+typedef int (*ExecForeignUpdate_function) (ResultRelInfo *resultRelInfo,
+ Datum rowid,
+ HeapTuple tuple);
These are not changed.

+typedef void (*EndForeignModify_function) (ResultRelInfo *resultRelInfo);

Also, it is not changed.

Thanks,
--
KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp>

Attachment Content-Type Size
pgsql-v9.3-writable-fdw-poc.v5.patch application/octet-stream 158.7 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2012-12-03 12:42:00 Re: [PATCH 11/14] Introduce wal decoding via catalog timetravel
Previous Message Alexander Korotkov 2012-12-03 12:31:31 Re: WIP: index support for regexp search