aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/postgres_fdw.c
diff options
context:
space:
mode:
authorEtsuro Fujita <efujita@postgresql.org>2019-06-13 17:59:09 +0900
committerEtsuro Fujita <efujita@postgresql.org>2019-06-13 17:59:09 +0900
commit8b6da83d162cb0ac9f6d21082727bbd45c972c53 (patch)
treedcc92fe5a15abb1349f78a77d52cfc115b46a78c /contrib/postgres_fdw/postgres_fdw.c
parent7dc6ae37def50b5344c157eee5e029a09359f8ee (diff)
downloadpostgresql-8b6da83d162cb0ac9f6d21082727bbd45c972c53.tar.gz
postgresql-8b6da83d162cb0ac9f6d21082727bbd45c972c53.zip
postgres_fdw: Account for triggers in non-direct remote UPDATE planning.
Previously, in postgresPlanForeignModify, we planned an UPDATE operation on a foreign table so that we transmit only columns that were explicitly targets of the UPDATE, so as to avoid unnecessary data transmission, but if there were BEFORE ROW UPDATE triggers on the foreign table, those triggers might change values for non-target columns, in which case we would miss sending changed values for those columns. Prevent optimizing away transmitting all columns if there are BEFORE ROW UPDATE triggers on the foreign table. This is an oversight in commit 7cbe57c34 which added triggers on foreign tables, so apply the patch all the way back to 9.4 where that came in. Author: Shohei Mochizuki Reviewed-by: Amit Langote Discussion: https://postgr.es/m/201905270152.x4R1q3qi014550@toshiba.co.jp
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 11451c2055d..3b874467f0f 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -1686,12 +1686,19 @@ postgresPlanForeignModify(PlannerInfo *root,
/*
* In an INSERT, we transmit all columns that are defined in the foreign
- * table. In an UPDATE, we transmit only columns that were explicitly
- * targets of the UPDATE, so as to avoid unnecessary data transmission.
- * (We can't do that for INSERT since we would miss sending default values
- * for columns not listed in the source statement.)
- */
- if (operation == CMD_INSERT)
+ * table. In an UPDATE, if there are BEFORE ROW UPDATE triggers on the
+ * foreign table, we transmit all columns like INSERT; else we transmit
+ * only columns that were explicitly targets of the UPDATE, so as to avoid
+ * unnecessary data transmission. (We can't do that for INSERT since we
+ * would miss sending default values for columns not listed in the source
+ * statement, and for UPDATE if there are BEFORE ROW UPDATE triggers since
+ * those triggers might change values for non-target columns, in which
+ * case we would miss sending changed values for those columns.)
+ */
+ if (operation == CMD_INSERT ||
+ (operation == CMD_UPDATE &&
+ rel->trigdesc &&
+ rel->trigdesc->trig_update_before_row))
{
TupleDesc tupdesc = RelationGetDescr(rel);
int attnum;