experimental-fix-for-transition-table-invalidation.patch
application/octet-stream
Filename: experimental-fix-for-transition-table-invalidation.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/setrefs.c | 5 | 0 |
| src/backend/parser/parse_relation.c | 6 | 0 |
| src/include/utils/queryenvironment.h | 1 | 0 |
| src/pl/plpgsql/src/pl_exec.c | 2 | 0 |
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 95338c8..b8bfe94 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -2582,6 +2582,11 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
if (rte->rtekind == RTE_RELATION)
context->glob->relationOids =
lappend_oid(context->glob->relationOids, rte->relid);
+ else if (rte->rtekind == RTE_NAMEDTUPLESTORE &&
+ OidIsValid(rte->relid))
+ context->glob->relationOids =
+ lappend_oid(context->glob->relationOids,
+ rte->relid);
}
/* And recurse into the query's subexpressions */
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index fdb149a..47d0d8c 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1991,6 +1991,12 @@ addRangeTableEntryForEnr(ParseState *pstate,
rte->rtekind = RTE_NAMEDTUPLESTORE;
/*
+ * Record dependency on a relation. This allows plans to be invalidated
+ * if they access transition tables linked to a table that is altered.
+ */
+ rte->relid = enrmd->dependrelid;
+
+ /*
* Build the list of effective column names using user-supplied aliases
* and/or actual column names. Also build the cannibalized fields.
*/
diff --git a/src/include/utils/queryenvironment.h b/src/include/utils/queryenvironment.h
index d5d22c2..c112ddf 100644
--- a/src/include/utils/queryenvironment.h
+++ b/src/include/utils/queryenvironment.h
@@ -26,6 +26,7 @@ typedef struct EnrmdData
{
char *name; /* name used to identify the relation */
TupleDesc tupdesc; /* description of result rows */
+ Oid dependrelid; /* OID of table this Enr depends on */
EnrType enrtype; /* to identify type of relation */
double enrtuples; /* estimated number of tuples */
} EnrmdData;
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index d9a4ef9..f8d89fd 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -703,6 +703,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
enr->md.name = trigdata->tg_trigger->tgnewtable;
enr->md.tupdesc = trigdata->tg_relation->rd_att;
+ enr->md.dependrelid = trigdata->tg_relation->rd_id;
enr->md.enrtuples = tuplestore_tuple_count(trigdata->tg_newtable);
enr->reldata = trigdata->tg_newtable;
register_enr(estate.queryEnv, enr);
@@ -716,6 +717,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
enr->md.name = trigdata->tg_trigger->tgoldtable;
enr->md.tupdesc = trigdata->tg_relation->rd_att;
+ enr->md.dependrelid = trigdata->tg_relation->rd_id;
enr->md.enrtuples = tuplestore_tuple_count(trigdata->tg_oldtable);
enr->reldata = trigdata->tg_oldtable;
register_enr(estate.queryEnv, enr);