On Tue, Apr 3, 2018 at 10:48 AM, Ashutosh Bapat <ashutosh.ba...@enterprisedb.com> wrote: >> >> 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. >
Previous patch didn't try to fold the ConvertRowtypeExpr::arg into a Const. postgres=# create table t1 (a int, b int, c int) partition by range(a); postgres=# create table t1p1 partition of t1 for values from (0) to (100) partition by range(b); postgres=# create table t1p1p1 partition of t1p1 for values from (0) to (50); postgres=# explain verbose select (1, 2, 3)::t1p1p1::t1p1::t1; -- notice Rowexpression here. QUERY PLAN ------------------------------------------- Result (cost=0.00..0.01 rows=1 width=32) Output: (ROW(1, 2, 3)::t1p1p1)::t1 (2 rows) Here's patch fixing that. With this patch postgres=# explain verbose select (1, 2, 3)::t1p1p1::t1p1::t1; QUERY PLAN ------------------------------------------- Result (cost=0.00..0.01 rows=1 width=32) Output: '(1,2,3)'::t1 (2 rows) -- Best Wishes, Ashutosh Bapat EnterpriseDB Corporation The Postgres Database Company
From aade26da4b45b96c82ac44ad93c7d8a9efc03dd2 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 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index ed6b680..d11cb72 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -3657,6 +3657,33 @@ eval_const_expressions_mutator(Node *node, context); } break; + case T_ConvertRowtypeExpr: + { + ConvertRowtypeExpr *cre = castNode(ConvertRowtypeExpr, node); + Node *arg; + ConvertRowtypeExpr *newcre; + + arg = eval_const_expressions_mutator((Node *) cre->arg, + context); + + /* + * In case of a nested ConvertRowtypeExpr, we can convert the + * leaf row directly to the topmost row format without any + * intermediate conversions. + */ + while (arg != NULL && IsA(arg, ConvertRowtypeExpr)) + arg = (Node *) castNode(ConvertRowtypeExpr, arg)->arg; + + newcre = makeNode(ConvertRowtypeExpr); + newcre->arg = (Expr *) arg; + newcre->resulttype = cre->resulttype; + newcre->convertformat = cre->convertformat; + newcre->location = cre->location; + + if (arg != NULL && IsA(arg, Const)) + return ece_evaluate_expr((Node *) newcre); + return (Node *) newcre; + } default: break; } -- 1.7.9.5