From 48f066bcf49cad67ce141cf490e9ae98c3f98568 Mon Sep 17 00:00:00 2001 From: amit Date: Wed, 9 Aug 2017 15:52:36 +0900 Subject: [PATCH 2/3] Teach expand_inherited_rtentry to use partition bound order After locking the child tables using find_all_inheritors, we discard the list of child table OIDs that it generates and rebuild the same using the information returned by RelationGetPartitionDispatchInfo. --- src/backend/optimizer/prep/prepunion.c | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 6d8f8938b2..e730c24ee4 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -33,6 +33,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "catalog/partition.h" #include "catalog/pg_inherits_fn.h" #include "catalog/pg_type.h" #include "miscadmin.h" @@ -1452,6 +1453,56 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) */ oldrelation = heap_open(parentOID, NoLock); + /* + * For partitioned tables, we arrange the child table OIDs such that they + * appear in the partition bound order. + */ + if (rte->relkind == RELKIND_PARTITIONED_TABLE) + { + List *leaf_part_oids; + int num_parted, + i; + PartitionDispatch *pds; + + /* Discard the original list. */ + list_free(inhOIDs); + inhOIDs = NIL; + + /* Request partitioning information. */ + pds = RelationGetPartitionDispatchInfo(oldrelation, &num_parted, + &leaf_part_oids); + + /* + * First collect the partitioned child table OIDs, which includes the + * root parent at the head. + */ + for (i = 0; i < num_parted; i++) + { + PartitionDispatch pd = pds[i]; + + inhOIDs = lappend_oid(inhOIDs, RelationGetRelid(pd->reldesc)); + } + + /* Concatenate the leaf partition OIDs. */ + inhOIDs = list_concat(inhOIDs, leaf_part_oids); + + /* + * Release the resources that RelationGetPartitionDispatchInfo + * acquired for us but we don't really need in this case. Note that + * we don't touch the root partitioned table itself by starting the + * loop with 1, not 0. + */ + for (i = 1; i < num_parted; i++) + { + PartitionDispatch pd = pds[i]; + + heap_close(pd->reldesc, NoLock); + ExecDropSingleTupleTableSlot(pd->tupslot); + if (pd->tupmap) + pfree(pd->tupmap); + } + } + /* Scan the inheritance set and expand it */ appinfos = NIL; has_child = false; -- 2.11.0