Hi, I am looking for feedback on the possibility of adding a table expansion hook to PostgreSQL (see attached patch). The motivation for this is to allow extensions to optimize table expansion. In particular, TimescaleDB does its own table expansion in order to apply a number of optimizations, including partition pruning (note that TimescaleDB uses inheritance since PostgreSQL 9.6 rather than declarative partitioning ). There's currently no official hook for table expansion, but TimescaleDB has been using the get_relation_info hook for this purpose. Unfortunately, PostgreSQL 12 broke this for us since it moved expansion to a later stage where we can no longer control it without some pretty bad hacks. Given that PostgreSQL 12 changed the expansion state of a table for the get_relation_info hook, we are thinking about this as a regression and are wondering if this could be considered against the head of PG 12 or maybe even PG 13 (although we realize feature freeze has been reached)?
The attached patch is against PostgreSQL master (commit fb544735) and is about ~10 lines of code. It doesn't change any existing behavior; it only allows getting control of expand_inherited_rtentry, which would make a huge difference for TimescaleDB. Best regards, Erik Engineering team lead Timescale
From 775102469a4c7e480c167e30ffd66d6555163f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstr=C3=B6m?= <e...@timescale.com> Date: Thu, 16 Apr 2020 13:20:48 +0200 Subject: [PATCH] Add a table expansion hook This change adds a table expansion hook that allows extensions to control expansion of inheritence relations (e.g., tables using inheritence or partitioning). Extensions might want to control expansion to enable optimizations to constraint exclusion or for access control on certain subtables. In PostgreSQL 12, table expansion moved to a much later stage of planning, which means that extensions that relied on expansion happening prior to, e.g., get_relation_info_hook no longer have the ability to control or editorialize table expansion. --- src/backend/optimizer/plan/initsplan.c | 7 ++++++- src/backend/optimizer/util/inherit.c | 3 +++ src/include/optimizer/inherit.h | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..358adf7413 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -159,7 +159,12 @@ add_other_rels_to_query(PlannerInfo *root) /* If it's marked as inheritable, look for children. */ if (rte->inh) - expand_inherited_rtentry(root, rel, rte, rti); + { + if (expand_inherited_rtentry_hook) + (*expand_inherited_rtentry_hook) (root, rel, rte, rti); + else + expand_inherited_rtentry(root, rel, rte, rti); + } } } diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index 3132fd35a5..2673e1a285 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -35,6 +35,9 @@ #include "utils/rel.h" +/* Hook for plugins to get control in expand_inherited_rtentry() */ +expand_inherited_rtentry_hook_type expand_inherited_rtentry_hook = NULL; + static void expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo, RangeTblEntry *parentrte, Index parentRTindex, Relation parentrel, diff --git a/src/include/optimizer/inherit.h b/src/include/optimizer/inherit.h index 0ba6132652..f0ccff2039 100644 --- a/src/include/optimizer/inherit.h +++ b/src/include/optimizer/inherit.h @@ -16,6 +16,14 @@ #include "nodes/pathnodes.h" +/* Hook for plugins to get control over expand_inherited_rtentry() */ +typedef void (*expand_inherited_rtentry_hook_type)(PlannerInfo *root, + RelOptInfo *rel, + RangeTblEntry *rte, + Index rti); + +extern PGDLLIMPORT expand_inherited_rtentry_hook_type expand_inherited_rtentry_hook; + extern void expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, Index rti); -- 2.25.1