fdw-plancache-inval-1.patch
text/x-diff
Filename: fdw-plancache-inval-1.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/setrefs.c | 72 | 0 |
| src/backend/utils/cache/plancache.c | 4 | 0 |
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index dd2b9ed..e7ddc14 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -16,7 +16,9 @@
#include "postgres.h"
#include "access/transam.h"
+#include "catalog/pg_class.h"
#include "catalog/pg_type.h"
+#include "foreign/foreign.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/pathnode.h"
@@ -150,6 +152,12 @@ static List *set_returning_clause_references(PlannerInfo *root,
static bool fix_opfuncids_walker(Node *node, void *context);
static bool extract_query_dependencies_walker(Node *node,
PlannerInfo *context);
+static void record_plan_foreign_table_dependency(PlannerInfo *root,
+ Oid ftid);
+static void record_plan_foreign_data_wrapper_dependency(PlannerInfo *root,
+ Oid fdwid);
+static void record_plan_foreign_server_dependency(PlannerInfo *root,
+ Oid serverid);
/*****************************************************************************
*
@@ -2652,6 +2660,54 @@ record_plan_function_dependency(PlannerInfo *root, Oid funcid)
}
/*
+ * record_plan_foreign_table_dependency
+ * Mark the current plan as depending on a particular foreign table.
+ */
+static void
+record_plan_foreign_table_dependency(PlannerInfo *root, Oid ftid)
+{
+ PlanInvalItem *inval_item = makeNode(PlanInvalItem);
+
+ inval_item->cacheId = FOREIGNTABLEREL;
+ inval_item->hashValue = GetSysCacheHashValue1(FOREIGNTABLEREL,
+ ObjectIdGetDatum(ftid));
+
+ root->glob->invalItems = lappend(root->glob->invalItems, inval_item);
+}
+
+/*
+ * record_plan_foreign_data_wrapper_dependency
+ * Mark the current plan as depending on a particular FDW.
+ */
+static void
+record_plan_foreign_data_wrapper_dependency(PlannerInfo *root, Oid fdwid)
+{
+ PlanInvalItem *inval_item = makeNode(PlanInvalItem);
+
+ inval_item->cacheId = FOREIGNDATAWRAPPEROID;
+ inval_item->hashValue = GetSysCacheHashValue1(FOREIGNDATAWRAPPEROID,
+ ObjectIdGetDatum(fdwid));
+
+ root->glob->invalItems = lappend(root->glob->invalItems, inval_item);
+}
+
+/*
+ * record_plan_foreign_server_dependency
+ * Mark the current plan as depending on a particular FDW.
+ */
+static void
+record_plan_foreign_server_dependency(PlannerInfo *root, Oid serverid)
+{
+ PlanInvalItem *inval_item = makeNode(PlanInvalItem);
+
+ inval_item->cacheId = FOREIGNSERVEROID;
+ inval_item->hashValue = GetSysCacheHashValue1(FOREIGNSERVEROID,
+ ObjectIdGetDatum(serverid));
+
+ root->glob->invalItems = lappend(root->glob->invalItems, inval_item);
+}
+
+/*
* extract_query_dependencies
* Given a not-yet-planned query or queries (i.e. a Query node or list
* of Query nodes), extract dependencies just as set_plan_references
@@ -2723,6 +2779,22 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
if (rte->rtekind == RTE_RELATION)
context->glob->relationOids =
lappend_oid(context->glob->relationOids, rte->relid);
+
+ if (rte->relkind == RELKIND_FOREIGN_TABLE)
+ {
+ ForeignTable *ftable;
+ ForeignServer *fserver;
+
+ ftable = GetForeignTable(rte->relid);
+ fserver = GetForeignServer(ftable->serverid);
+
+ record_plan_foreign_table_dependency(context,
+ ftable->relid);
+ record_plan_foreign_server_dependency(context,
+ ftable->serverid);
+ record_plan_foreign_data_wrapper_dependency(context,
+ fserver->fdwid);
+ }
}
/* And recurse into the query's subexpressions */
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 8fd9f2b..a1af0c1 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -124,6 +124,10 @@ InitPlanCache(void)
CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
/* User mapping change may invalidate plans with pushed down foreign join */
CacheRegisterSyscacheCallback(USERMAPPINGOID, PlanCacheUserMappingCallback, (Datum) 0);
+ /* Foreign table/data wrapper/server alterations invalidate any related plans */
+ CacheRegisterSyscacheCallback(FOREIGNTABLEREL, PlanCacheFuncCallback, (Datum) 0);
+ CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheFuncCallback, (Datum) 0);
+ CacheRegisterSyscacheCallback(FOREIGNSERVEROID, PlanCacheFuncCallback, (Datum) 0);
}
/*