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