On Mon, Apr 2, 2018 at 1:40 AM, Andres Freund <and...@anarazel.de> wrote:
> Hi,
>
> On 2018-02-26 17:20:05 +0530, Ashutosh Bapat wrote:
>> In a multi-level partitioned table, a parent whole-row reference gets
>> translated into nested ConvertRowtypeExpr with child whole-row
>> reference as the leaf. During the execution, the child whole-row
>> reference gets translated into all all intermediate parents' whole-row
>> references, ultimately represented as parent's whole-row reference.
>> AFAIU, the intermediate translations are unnecessary. The leaf child
>> whole-row can be directly translated into top parent's whole-row
>> reference. Here's a WIP patch which does that by eliminating
>> intermediate ConvertRowtypeExprs during ExecInitExprRec().
>
> Why is this done appropriately at ExecInitExpr() time, rather than at
> plan time? Seems like eval_const_expressions() would be a bit more
> appropriate (being badly named aside...)?

That seems to be a better idea. Here's patch.

-- 
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
From b99ae826931516a7c6ad981435e8ac9ef754f15e Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.ba...@enterprisedb.com>
Date: Tue, 3 Apr 2018 09:00:19 +0530
Subject: [PATCH] Optimize nested ConvertRowtypeExprs

A ConvertRowtypeExprs is used to translate a whole-row reference of a
child to that of a parent. The planner produces nested
ConvertRowtypeExpr while translating whole-row reference of a leaf
partition in a multi-level partition hierarchy. Executor then
translates the whole-row reference from the leaf partition into all
the intermediate parent's whole-row references before arriving at the
final whole-row reference. It could instead translate the whole-row
reference from the leaf partition directly to the top-most parent's
whole-row reference skipping any intermediate translations.

Ashutosh Bapat, reviewed by Andres Freund.
---
 src/backend/optimizer/util/clauses.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index ed6b680..3af5033 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -3657,6 +3657,31 @@ eval_const_expressions_mutator(Node *node,
 													  context);
 			}
 			break;
+		case T_ConvertRowtypeExpr:
+			{
+				ConvertRowtypeExpr *cre = castNode(ConvertRowtypeExpr, node);
+				Expr	   *arg = cre->arg;
+				ConvertRowtypeExpr *newcre;
+
+				/*
+				 * In case of a nested ConvertRowtypeExpr, we can convert the
+				 * leaf row directly to the topmost row format without any
+				 * intermediate conversions.
+				 */
+				Assert(arg != NULL);
+				while (IsA(arg, ConvertRowtypeExpr))
+					arg = castNode(ConvertRowtypeExpr, arg)->arg;
+
+				newcre = makeNode(ConvertRowtypeExpr);
+				newcre->arg = arg;
+				newcre->resulttype = cre->resulttype;
+				newcre->convertformat = cre->convertformat;
+				newcre->location = newcre->location;
+
+				if (IsA(arg, Const))
+					return ece_evaluate_expr((Node *) newcre);
+				return (Node *) newcre;
+			}
 		default:
 			break;
 	}
-- 
1.7.9.5

Reply via email to