From d3b4761a53d8817922b0a6a7aae0fc19c70f28df Mon Sep 17 00:00:00 2001 From: "Andrey V. Lepikhov" Date: Mon, 9 Oct 2023 15:31:04 +0700 Subject: [PATCH] Be careful allowing custom nodes to use CTE and Subplan links in the targetlist. Add a paragraph in documentation, comment in the place of the error triggers and assert to quickly detect problem at the developing stage. --- doc/src/sgml/custom-scan.sgml | 4 ++++ src/backend/utils/adt/ruleutils.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/doc/src/sgml/custom-scan.sgml b/doc/src/sgml/custom-scan.sgml index a200d502cd..0bc65cbd06 100644 --- a/doc/src/sgml/custom-scan.sgml +++ b/doc/src/sgml/custom-scan.sgml @@ -206,6 +206,10 @@ typedef struct CustomScan the actual scan tuples. custom_scan_tlist must be provided for joins, and could be provided for scans if the custom scan provider can compute some non-Var expressions. + Don't include into custom_scan_tlist references to CTE + or SubPlan entries because it directly points to the list of RangeTableEntries. + In most cases it doesn't cause any issues but during the EXPLAIN ANALYZE it can fail + to find proper subplan during preparing textual representation of targetlist. custom_relids is set by the core code to the set of relations (range table indexes) that this scan node handles; except when this scan is replacing a join, it will have only one member. diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 442205382e..a60268dcac 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -7860,6 +7860,16 @@ get_name_for_var_field(Var *var, int fieldno, deparse_namespace save_dpns; const char *result; + /* + * Limitation, related to CustomScan nodes. + * custom_scan_tlist points to the range table entries + * directly. In the case of CTEs and subqueries we have some + * sort of uncertainity here: only the developer of the + * custom node knows from which subtree they get the subplan + * link. + */ + Assert(!IsA(dpns->plan, CustomScan)); + if (!dpns->inner_plan) elog(ERROR, "failed to find plan for subquery %s", rte->eref->aliasname); @@ -7982,6 +7992,16 @@ get_name_for_var_field(Var *var, int fieldno, deparse_namespace save_dpns; const char *result; + /* + * Limitation, related to CustomScan nodes. + * custom_scan_tlist points to the range table entries + * directly. In the case of CTEs and subqueries we have some + * sort of uncertainity here: only the developer of the + * custom node knows from which subtree they get the subplan + * link. + */ + Assert(!IsA(dpns->plan, CustomScan)); + if (!dpns->inner_plan) elog(ERROR, "failed to find plan for CTE %s", rte->eref->aliasname); -- 2.42.0