summaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/postgres_fdw')
-rw-r--r--contrib/postgres_fdw/expected/postgres_fdw.out1
-rw-r--r--contrib/postgres_fdw/option.c8
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c47
-rw-r--r--contrib/postgres_fdw/sql/postgres_fdw.sql1
4 files changed, 55 insertions, 2 deletions
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 7a13d011d5c..38c6cf81623 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -79,6 +79,7 @@ ALTER FOREIGN TABLE ft2 DROP COLUMN cx;
-- configure options
ALTER SERVER testserver1 OPTIONS (
use_remote_estimate 'false',
+ updatable 'true',
fdw_startup_cost '123.456',
fdw_tuple_cost '0.123',
service 'value',
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index 123cb4f0104..e1d4c477339 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -106,9 +106,10 @@ postgres_fdw_validator(PG_FUNCTION_ARGS)
/*
* Validate option value, when we can do so without any context.
*/
- if (strcmp(def->defname, "use_remote_estimate") == 0)
+ if (strcmp(def->defname, "use_remote_estimate") == 0 ||
+ strcmp(def->defname, "updatable") == 0)
{
- /* use_remote_estimate accepts only boolean values */
+ /* these accept only boolean values */
(void) defGetBoolean(def);
}
else if (strcmp(def->defname, "fdw_startup_cost") == 0 ||
@@ -151,6 +152,9 @@ InitPgFdwOptions(void)
/* cost factors */
{"fdw_startup_cost", ForeignServerRelationId, false},
{"fdw_tuple_cost", ForeignServerRelationId, false},
+ /* updatable is available on both server and table */
+ {"updatable", ForeignServerRelationId, false},
+ {"updatable", ForeignTableRelationId, false},
{NULL, InvalidOid, false}
};
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index cbfecc4dd42..1c93e0c5ac3 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -277,6 +277,7 @@ static TupleTableSlot *postgresExecForeignDelete(EState *estate,
TupleTableSlot *planSlot);
static void postgresEndForeignModify(EState *estate,
ResultRelInfo *resultRelInfo);
+static int postgresIsForeignRelUpdatable(Relation rel);
static void postgresExplainForeignScan(ForeignScanState *node,
ExplainState *es);
static void postgresExplainForeignModify(ModifyTableState *mtstate,
@@ -355,6 +356,7 @@ postgres_fdw_handler(PG_FUNCTION_ARGS)
routine->ExecForeignUpdate = postgresExecForeignUpdate;
routine->ExecForeignDelete = postgresExecForeignDelete;
routine->EndForeignModify = postgresEndForeignModify;
+ routine->IsForeignRelUpdatable = postgresIsForeignRelUpdatable;
/* Support functions for EXPLAIN */
routine->ExplainForeignScan = postgresExplainForeignScan;
@@ -1597,6 +1599,51 @@ postgresEndForeignModify(EState *estate,
}
/*
+ * postgresIsForeignRelUpdatable
+ * Determine whether a foreign table supports INSERT, UPDATE and/or
+ * DELETE.
+ */
+static int
+postgresIsForeignRelUpdatable(Relation rel)
+{
+ bool updatable;
+ ForeignTable *table;
+ ForeignServer *server;
+ ListCell *lc;
+
+ /*
+ * By default, all postgres_fdw foreign tables are assumed updatable. This
+ * can be overridden by a per-server setting, which in turn can be
+ * overridden by a per-table setting.
+ */
+ updatable = true;
+
+ table = GetForeignTable(RelationGetRelid(rel));
+ server = GetForeignServer(table->serverid);
+
+ foreach(lc, server->options)
+ {
+ DefElem *def = (DefElem *) lfirst(lc);
+
+ if (strcmp(def->defname, "updatable") == 0)
+ updatable = defGetBoolean(def);
+ }
+ foreach(lc, table->options)
+ {
+ DefElem *def = (DefElem *) lfirst(lc);
+
+ if (strcmp(def->defname, "updatable") == 0)
+ updatable = defGetBoolean(def);
+ }
+
+ /*
+ * Currently "updatable" means support for INSERT, UPDATE and DELETE.
+ */
+ return updatable ?
+ (1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE) : 0;
+}
+
+/*
* postgresExplainForeignScan
* Produce extra output for EXPLAIN of a ForeignScan on a foreign table
*/
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 19221680bf1..ce8bb7597ba 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -88,6 +88,7 @@ ALTER FOREIGN TABLE ft2 DROP COLUMN cx;
-- configure options
ALTER SERVER testserver1 OPTIONS (
use_remote_estimate 'false',
+ updatable 'true',
fdw_startup_cost '123.456',
fdw_tuple_cost '0.123',
service 'value',