summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2021-01-18 23:32:30 +0000
committerTom Lane2021-01-18 23:32:30 +0000
commit60661bbf2dca0c1e744c948c74bccab98933c45b (patch)
tree67c221d1200a479692dc72f6436756d2db50c704
parent3fd80c728dc36fbd250ca3019c2f5fa2567f1a75 (diff)
Avoid crash with WHERE CURRENT OF and a custom scan plan.
execCurrent.c's search_plan_tree() assumed that ForeignScanStates and CustomScanStates necessarily have a valid ss_currentRelation. This is demonstrably untrue for postgres_fdw's remote join and remote aggregation plans, and non-leaf custom scans might not have an identifiable scan relation either. Avoid crashing by ignoring such nodes when the field is null. This solution will lead to errors like 'cursor "foo" is not a simply updatable scan of table "bar"' in cases where maybe we could have allowed WHERE CURRENT OF to work. That's not an issue for postgres_fdw's usages, since joins or aggregations would render WHERE CURRENT OF invalid anyway. But an otherwise-transparent upper level custom scan node might find this annoying. When and if someone cares to expend work on such a scenario, we could invent a custom-scan-provider callback to determine what's safe. Report and patch by David Geier, commentary by me. It's been like this for awhile, so back-patch to all supported branches. Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/backend/executor/execCurrent.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/backend/executor/execCurrent.c b/src/backend/executor/execCurrent.c
index 0852bb9cec8..ff42cdd8088 100644
--- a/src/backend/executor/execCurrent.c
+++ b/src/backend/executor/execCurrent.c
@@ -317,7 +317,12 @@ search_plan_tree(PlanState *node, Oid table_oid,
switch (nodeTag(node))
{
/*
- * Relation scan nodes can all be treated alike
+ * Relation scan nodes can all be treated alike. Note that
+ * ForeignScan and CustomScan might not have a currentRelation, in
+ * which case we just ignore them. (We dare not descend to any
+ * child plan nodes they might have, since we do not know the
+ * relationship of such a node's current output tuple to the
+ * children's current outputs.)
*/
case T_SeqScanState:
case T_SampleScanState:
@@ -330,7 +335,8 @@ search_plan_tree(PlanState *node, Oid table_oid,
{
ScanState *sstate = (ScanState *) node;
- if (RelationGetRelid(sstate->ss_currentRelation) == table_oid)
+ if (sstate->ss_currentRelation &&
+ RelationGetRelid(sstate->ss_currentRelation) == table_oid)
result = sstate;
break;
}