On Tue, Apr 3, 2018 at 10:48 AM, Ashutosh Bapat
<[email protected]> 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 <[email protected]>
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