0002-Handle-ConvertRowtypeExprs-in-pull_vars_clause.patch
text/x-diff
Filename: 0002-Handle-ConvertRowtypeExprs-in-pull_vars_clause.patch
Type: text/x-diff
Part: 4
From a8a04a7cd426b3d9c8b037fb31e91970c9651097 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>
Date: Mon, 25 Dec 2023 16:08:15 +0300
Subject: [PATCH 2/6] Handle ConvertRowtypeExprs in pull_vars_clause().
This is a preparatory patch to fix the unresolved ConvertRowtypeExpr
references in the targetlists. The patch allows pull_vars_clause() to
return ConvertRowtypeExprs without recursing into those. Because of
the recent work to support indexes and triggers on partitioned table,
every caller of pull_var_clause() can encounter a ConvertRowtype
embedding a whole-row reference. Current behavior is unchanged.
Callers which don't need to recurse to ConvertRowtypeExprs
should explicitly pass PVC_INCLUDE_CONVERTROWTYPES.
The patch is taken from https://www.postgresql.org/message-id/CAFjFpRc8ZoDm0%2Bzhx%2BMckwGyEqkOzWcpVqbvjaxwdGarZSNrmA%40mail.gmail.com
---
src/backend/nodes/nodeFuncs.c | 32 ++++++++++++++++++++++++++++
src/backend/optimizer/plan/setrefs.c | 32 ----------------------------
src/backend/optimizer/util/var.c | 18 ++++++++++++++++
src/include/nodes/nodeFuncs.h | 1 +
src/include/optimizer/optimizer.h | 2 ++
5 files changed, 53 insertions(+), 32 deletions(-)
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 50705a1e158..38964ecfae2 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -4806,3 +4806,35 @@ planstate_walk_members(PlanState **planstates, int nplans,
return false;
}
+
+/*
+ * is_converted_whole_row_reference
+ * If the given node is a ConvertRowtypeExpr encapsulating a whole-row
+ * reference as implicit cast (i.e a parent's whole row reference
+ * translated by adjust_appendrel_attrs()), return true. Otherwise return
+ * false.
+ */
+bool
+is_converted_whole_row_reference(Node *node)
+{
+ ConvertRowtypeExpr *convexpr;
+
+ if (!node || !IsA(node, ConvertRowtypeExpr))
+ return false;
+
+ /* Traverse nested ConvertRowtypeExpr's. */
+ convexpr = castNode(ConvertRowtypeExpr, node);
+ while (convexpr->convertformat == COERCE_IMPLICIT_CAST &&
+ IsA(convexpr->arg, ConvertRowtypeExpr))
+ convexpr = castNode(ConvertRowtypeExpr, convexpr->arg);
+
+ if (IsA(convexpr->arg, Var))
+ {
+ Var *var = castNode(Var, convexpr->arg);
+
+ if (var->varattno == 0)
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 0bf1ca3910b..eaaac7edf7d 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -214,8 +214,6 @@ static List *set_windowagg_runcondition_references(PlannerInfo *root,
List *runcondition,
Plan *plan);
-static bool is_converted_whole_row_reference(Node *node);
-
/*****************************************************************************
*
* SUBPLAN REFERENCES
@@ -3668,33 +3666,3 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
return expression_tree_walker(node, extract_query_dependencies_walker,
context);
}
-
-/*
- * is_converted_whole_row_reference
- * If the given node is a ConvertRowtypeExpr encapsulating a whole-row
- * reference as implicit cast, return true. Otherwise return false.
- */
-static bool
-is_converted_whole_row_reference(Node *node)
-{
- ConvertRowtypeExpr *convexpr;
-
- if (!node || !IsA(node, ConvertRowtypeExpr))
- return false;
-
- /* Traverse nested ConvertRowtypeExpr's. */
- convexpr = castNode(ConvertRowtypeExpr, node);
- while (convexpr->convertformat == COERCE_IMPLICIT_CAST &&
- IsA(convexpr->arg, ConvertRowtypeExpr))
- convexpr = castNode(ConvertRowtypeExpr, convexpr->arg);
-
- if (IsA(convexpr->arg, Var))
- {
- Var *var = castNode(Var, convexpr->arg);
-
- if (var->varattno == 0)
- return true;
- }
-
- return false;
-}
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 5f721eb8e13..99d1efc4c60 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -591,6 +591,11 @@ locate_var_of_level_walker(Node *node,
* Vars within a PHV's expression are included in the result only
* when PVC_RECURSE_PLACEHOLDERS is specified.
*
+ * ConvertRowtypeExprs encapsulating whole row references are handled
+ * according to these bits in 'flags':
+ * PVC_INCLUDE_CONVERTROWTYPES include ConvertRowtypeExprs in output list
+ * by default - recurse into ConvertRowtypeExprs arguments
+ *
* GroupingFuncs are treated exactly like Aggrefs, and so do not need
* their own flag bits.
*
@@ -704,6 +709,19 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
else
elog(ERROR, "PlaceHolderVar found where not expected");
}
+ else if (is_converted_whole_row_reference(node))
+ {
+ if (context->flags & PVC_INCLUDE_CONVERTROWTYPES)
+ {
+ context->varlist = lappend(context->varlist, node);
+ /* we do NOT descend into the contained expression */
+ return false;
+ }
+ else
+ {
+ /* fall through to recurse into the ConvertRowtype's argument. */
+ }
+ }
return expression_tree_walker(node, pull_var_clause_walker, context);
}
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index caefc39f6a2..d43e87e2402 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -221,4 +221,5 @@ extern bool planstate_tree_walker_impl(struct PlanState *planstate,
planstate_tree_walker_callback walker,
void *context);
+extern bool is_converted_whole_row_reference(Node *node);
#endif /* NODEFUNCS_H */
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 2e123e08b79..b1f83fafdc8 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -192,6 +192,8 @@ extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref,
* output list */
#define PVC_RECURSE_PLACEHOLDERS 0x0020 /* recurse into PlaceHolderVar
* arguments */
+#define PVC_INCLUDE_CONVERTROWTYPES 0x0040 /* include ConvertRowtypeExprs in
+ * output list */
extern Bitmapset *pull_varnos(PlannerInfo *root, Node *node);
extern Bitmapset *pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup);
--
2.43.0