0002-Prevent-a-redundant-ConvertRowtypeExpr-node.patch

application/octet-stream

Filename: 0002-Prevent-a-redundant-ConvertRowtypeExpr-node.patch
Type: application/octet-stream
Part: 1
Message: Re: UPDATE of partition key

Patch

Format: format-patch
Series: patch 0002
Subject: Prevent a redundant ConvertRowtypeExpr node.
File+
src/backend/rewrite/rewriteManip.c 42 11
From 4541795a758ab729b5015d1f878abd2f1d1eae6a Mon Sep 17 00:00:00 2001
From: Amit Khandekar <amit.khandekar@enterprisedb.com>
Date: Wed, 4 Oct 2017 18:20:49 +0530
Subject: [PATCH 2/2] Prevent a redundant ConvertRowtypeExpr node.

In case RETURNING clause has a whole row var, for mapping this whole
row var from parent to child, we add a ConvertRowtypeExpr node on top
of the whole row var. This node's final result type is the parent
composite type. But for mapping a whole row var from one child
partition to the other child partitions, the child expression can
already have a ConvertRowtypeExpr. In such case, prevent another
ConvertRowtypeExpr expression on top of it. Instead, modify the
containing var of the already-existing ConvertRowtypeExpr.
---
 src/backend/rewrite/rewriteManip.c | 53 ++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 11 deletions(-)

diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index c5773ef..9290c7f 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -1224,6 +1224,7 @@ typedef struct
 	/* Target type when converting whole-row vars */
 	Oid			to_rowtype;
 	bool	   *found_whole_row;	/* output flag */
+	bool		coerced_var;	/* var is under ConvertRowTypeExpr */
 } map_variable_attnos_context;
 
 static Node *
@@ -1267,22 +1268,29 @@ map_variable_attnos_mutator(Node *node,
 					/* Don't convert unless necessary. */
 					if (context->to_rowtype != var->vartype)
 					{
-						ConvertRowtypeExpr *r;
-
 						/* Var itself is converted to the requested type. */
 						newvar->vartype = context->to_rowtype;
 
 						/*
-						 * And a conversion node on top to convert back to the
-						 * original type.
+						 * If this var is already under a ConvertRowtypeExpr,
+						 * we don't have to add another one.
 						 */
-						r = makeNode(ConvertRowtypeExpr);
-						r->arg = (Expr *) newvar;
-						r->resulttype = var->vartype;
-						r->convertformat = COERCE_IMPLICIT_CAST;
-						r->location = -1;
-
-						return (Node *) r;
+						if (!context->coerced_var)
+						{
+							ConvertRowtypeExpr *r;
+
+							/*
+							 * And a conversion node on top to convert back to
+							 * the original type.
+							 */
+							r = makeNode(ConvertRowtypeExpr);
+							r->arg = (Expr *) newvar;
+							r->resulttype = var->vartype;
+							r->convertformat = COERCE_IMPLICIT_CAST;
+							r->location = -1;
+
+							return (Node *) r;
+						}
 					}
 				}
 			}
@@ -1290,6 +1298,28 @@ map_variable_attnos_mutator(Node *node,
 		}
 		/* otherwise fall through to copy the var normally */
 	}
+	else if (IsA(node, ConvertRowtypeExpr))
+	{
+		ConvertRowtypeExpr *r = (ConvertRowtypeExpr *) node;
+
+		/*
+		 * If this is coercing a var (which is typical), convert only the var,
+		 * as against adding another ConvertRowtypeExpr over it.
+		 */
+		if (IsA(r->arg, Var))
+		{
+			ConvertRowtypeExpr *newnode;
+
+			newnode = (ConvertRowtypeExpr *) palloc(sizeof(ConvertRowtypeExpr));
+			*newnode = *r;
+			context->coerced_var = true;
+			newnode->arg = (Expr *) map_variable_attnos_mutator((Node *) r->arg, context);
+			context->coerced_var = false;
+
+			return (Node *) newnode;
+		}
+		/* Else fall through the expression tree mutator */
+	}
 	else if (IsA(node, Query))
 	{
 		/* Recurse into RTE subquery or not-yet-planned sublink subquery */
@@ -1321,6 +1351,7 @@ map_variable_attnos(Node *node,
 	context.map_length = map_length;
 	context.to_rowtype = to_rowtype;
 	context.found_whole_row = found_whole_row;
+	context.coerced_var = false;
 
 	*found_whole_row = false;
 
-- 
2.1.4