public inbox for [email protected]
help / color / mirror / Atom feedFrom: Alvaro Herrera <[email protected]>
Subject: [PATCH v3 3/3] fixups
Date: Wed, 28 Feb 2018 20:20:08 -0300
---
src/backend/catalog/partition.c | 52 ++++++++++++----------
src/backend/executor/execPartition.c | 81 +++++++++++++---------------------
src/backend/optimizer/prep/prepunion.c | 59 ++++++++++++++++++++-----
src/include/optimizer/prep.h | 15 +++----
4 files changed, 115 insertions(+), 92 deletions(-)
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 9d1ad09595..ef2ef3aa80 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -192,7 +192,7 @@ static int get_partition_bound_num_indexes(PartitionBoundInfo b);
static int get_greatest_modulus(PartitionBoundInfo b);
static uint64 compute_hash_value(int partnatts, FmgrInfo *partsupfunc,
Datum *values, bool *isnull);
-static Oid get_partition_parent_recurse(Oid relid, bool getroot);
+static Oid get_partition_parent_recurse(Relation inhRel, Oid relid, bool getroot);
/*
* RelationBuildPartitionDesc
@@ -1385,8 +1385,10 @@ check_default_allows_bound(Relation parent, Relation default_rel,
/*
* get_partition_parent
+ * Obtain direct parent or topmost ancestor of given relation
*
- * Returns inheritance parent of a partition by scanning pg_inherits
+ * Returns direct inheritance parent of a partition by scanning pg_inherits;
+ * or, if 'getroot' is true, the topmost parent in the inheritance hierarchy.
*
* Note: Because this function assumes that the relation whose OID is passed
* as an argument will have precisely one parent, it should only be called
@@ -1395,26 +1397,32 @@ check_default_allows_bound(Relation parent, Relation default_rel,
Oid
get_partition_parent(Oid relid, bool getroot)
{
- Oid parentOid = get_partition_parent_recurse(relid, getroot);
+ Relation inhRel;
+ Oid parentOid;
+ inhRel = heap_open(InheritsRelationId, AccessShareLock);
+
+ parentOid = get_partition_parent_recurse(inhRel, relid, getroot);
if (parentOid == InvalidOid)
elog(ERROR, "could not find parent of relation %u", relid);
+ heap_close(inhRel, AccessShareLock);
+
return parentOid;
}
+/*
+ * get_partition_parent_recurse
+ * Recursive part of get_partition_parent
+ */
static Oid
-get_partition_parent_recurse(Oid relid, bool getroot)
+get_partition_parent_recurse(Relation inhRel, Oid relid, bool getroot)
{
- Form_pg_inherits form;
- Relation catalogRelation;
SysScanDesc scan;
ScanKeyData key[2];
HeapTuple tuple;
Oid result = InvalidOid;
- catalogRelation = heap_open(InheritsRelationId, AccessShareLock);
-
ScanKeyInit(&key[0],
Anum_pg_inherits_inhrelid,
BTEqualStrategyNumber, F_OIDEQ,
@@ -1424,28 +1432,26 @@ get_partition_parent_recurse(Oid relid, bool getroot)
BTEqualStrategyNumber, F_INT4EQ,
Int32GetDatum(1));
- scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true,
+ /* Obtain the direct parent, and release resources before recursing */
+ scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true,
NULL, 2, key);
-
tuple = systable_getnext(scan);
if (HeapTupleIsValid(tuple))
- {
- form = (Form_pg_inherits) GETSTRUCT(tuple);
- result = form->inhparent;
-
- if (getroot)
- result = get_partition_parent_recurse(result, getroot);
- }
-
+ result = ((Form_pg_inherits) GETSTRUCT(tuple))->inhparent;
systable_endscan(scan);
- heap_close(catalogRelation, AccessShareLock);
/*
- * If we recursed and got InvalidOid as parent, that means we reached the
- * root of this partition tree in the form of 'relid' itself.
+ * If we were asked to recurse, do so now. Except that if we didn't get a
+ * valid parent, then the 'relid' argument was already the topmost parent,
+ * so return that.
*/
- if (getroot && !OidIsValid(result))
- return relid;
+ if (getroot)
+ {
+ if (OidIsValid(result))
+ return get_partition_parent_recurse(inhRel, result, getroot);
+ else
+ return relid;
+ }
return result;
}
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 3f7b61dc37..7ea0295d3c 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -65,6 +65,7 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, Relation rel)
int num_update_rri = 0,
update_rri_index = 0;
PartitionTupleRouting *proute;
+ int nparts;
/*
* Get the information about the partition tree after locking all the
@@ -75,14 +76,12 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, Relation rel)
proute->partition_dispatch_info =
RelationGetPartitionDispatchInfo(rel, &proute->num_dispatch,
&leaf_parts);
- proute->num_partitions = list_length(leaf_parts);
- proute->partitions = (ResultRelInfo **) palloc(proute->num_partitions *
- sizeof(ResultRelInfo *));
+ proute->num_partitions = nparts = list_length(leaf_parts);
+ proute->partitions =
+ (ResultRelInfo **) palloc(nparts * sizeof(ResultRelInfo *));
proute->parent_child_tupconv_maps =
- (TupleConversionMap **) palloc0(proute->num_partitions *
- sizeof(TupleConversionMap *));
- proute->partition_oids = (Oid *) palloc(proute->num_partitions *
- sizeof(Oid));
+ (TupleConversionMap **) palloc0(nparts * sizeof(TupleConversionMap *));
+ proute->partition_oids = (Oid *) palloc(nparts * sizeof(Oid));
/* Set up details specific to the type of tuple routing we are doing. */
if (mtstate && mtstate->operation == CMD_UPDATE)
@@ -116,15 +115,12 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, Relation rel)
*/
if (mtstate && mtstate->mt_onconflict != ONCONFLICT_NONE)
{
- proute->partition_arbiter_indexes = (List **)
- palloc(proute->num_partitions *
- sizeof(List *));
- proute->partition_conflproj_slots = (TupleTableSlot **)
- palloc(proute->num_partitions *
- sizeof(TupleTableSlot *));
- proute->partition_existing_slots = (TupleTableSlot **)
- palloc(proute->num_partitions *
- sizeof(TupleTableSlot *));
+ proute->partition_arbiter_indexes =
+ (List **) palloc(nparts * sizeof(List *));
+ proute->partition_conflproj_slots =
+ (TupleTableSlot **) palloc(nparts * sizeof(TupleTableSlot *));
+ proute->partition_existing_slots =
+ (TupleTableSlot **) palloc(nparts * sizeof(TupleTableSlot *));
}
i = 0;
@@ -537,48 +533,33 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
{
/* Convert expressions contain partition's attnos. */
List *conv_setproj;
- AppendRelInfo appinfo;
TupleDesc tupDesc;
/* Need our own slot. */
part_existing_slot =
ExecInitExtraTupleSlot(mtstate->ps.state, partrelDesc);
- /* First convert references to EXCLUDED pseudo-relation. */
- conv_setproj = map_partition_varattnos((List *)
- node->onConflictSet,
- INNER_VAR,
- partrel,
- firstResultRel, NULL);
+ /*
+ * First convert references to the EXCLUDED pseudo-relation, which
+ * was set to INNER_VAR by set_plan_references.
+ */
+ conv_setproj =
+ map_partition_varattnos((List *) node->onConflictSet,
+ INNER_VAR, partrel,
+ firstResultRel, NULL);
+
/* Then convert references to main target relation. */
- conv_setproj = map_partition_varattnos((List *)
- conv_setproj,
- firstVarno,
- partrel,
- firstResultRel, NULL);
+ conv_setproj =
+ map_partition_varattnos((List *) conv_setproj,
+ firstVarno, partrel,
+ firstResultRel, NULL);
- /*
- * Need to fix the target entries' resnos too by using
- * inheritance translation.
- */
- appinfo.type = T_AppendRelInfo;
- appinfo.parent_relid = firstVarno;
- appinfo.parent_reltype = firstResultRel->rd_rel->reltype;
- appinfo.child_relid = partrel->rd_id;
- appinfo.child_reltype = partrel->rd_rel->reltype;
- appinfo.parent_reloid = firstResultRel->rd_id;
- make_inh_translation_list(firstResultRel, partrel,
- 1, /* dummy */
- &appinfo.translated_vars);
- conv_setproj = adjust_inherited_tlist((List *) conv_setproj,
- &appinfo);
-
- /*
- * Add any attributes that are missing in the source list, such
- * as, dropped columns in the partition.
- */
- conv_setproj = expand_targetlist(conv_setproj, CMD_UPDATE,
- firstVarno, partrel);
+ conv_setproj =
+ adjust_and_expand_partition_tlist(RelationGetDescr(firstResultRel),
+ RelationGetDescr(partrel),
+ RelationGetRelationName(partrel),
+ firstVarno,
+ conv_setproj);
tupDesc = ExecTypeFromTL(conv_setproj, partrelDesc->tdhasoid);
part_conflproj_slot = ExecInitExtraTupleSlot(mtstate->ps.state,
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 4153891f29..c11f6c20ab 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -124,6 +124,8 @@ static Node *adjust_appendrel_attrs_mutator(Node *node,
adjust_appendrel_attrs_context *context);
static Relids adjust_child_relids(Relids relids, int nappinfos,
AppendRelInfo **appinfos);
+static List *adjust_inherited_tlist(List *tlist,
+ AppendRelInfo *context);
/*
@@ -2357,7 +2359,7 @@ adjust_child_relids_multilevel(PlannerInfo *root, Relids relids,
*
* Note that this is not needed for INSERT because INSERT isn't inheritable.
*/
-List *
+static List *
adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
{
bool changed_it = false;
@@ -2379,8 +2381,10 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
continue; /* ignore junk items */
/*
- * ignore dummy tlist entry added by exapnd_targetlist() for
- * dropped columns in the parent table.
+ * XXX ugly hack: must ignore dummy tlist entry added by
+ * expand_targetlist() for dropped columns in the parent table or we
+ * fail because there is no translation. Must find a better way to
+ * deal with this case, though.
*/
if (IsA(tle->expr, Const) && ((Const *) tle->expr)->constisnull)
continue;
@@ -2423,10 +2427,7 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
if (tle->resjunk)
continue; /* ignore junk items */
- /*
- * ignore dummy tlist entry added by exapnd_targetlist() for
- * dropped columns in the parent table.
- */
+ /* XXX ugly hack; see above */
if (IsA(tle->expr, Const) && ((Const *) tle->expr)->constisnull)
continue;
@@ -2444,10 +2445,7 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
if (!tle->resjunk)
continue; /* here, ignore non-junk items */
- /*
- * ignore dummy tlist entry added by exapnd_targetlist() for
- * dropped columns in the parent table.
- */
+ /* XXX ugly hack; see above */
if (IsA(tle->expr, Const) && ((Const *) tle->expr)->constisnull)
continue;
@@ -2460,6 +2458,45 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
}
/*
+ * Given a targetlist for the parentRel of the given varno, adjust it to be in
+ * the correct order and to contain all the needed elements for the given
+ * partition.
+ */
+List *
+adjust_and_expand_partition_tlist(TupleDesc parentDesc,
+ TupleDesc partitionDesc,
+ char *partitionRelname,
+ int parentVarno,
+ List *targetlist)
+{
+ AppendRelInfo appinfo;
+ List *result_tl;
+
+ /*
+ * Fist, fix the target entries' resnos, by using inheritance translation.
+ */
+ appinfo.type = T_AppendRelInfo;
+ appinfo.parent_relid = parentVarno;
+ appinfo.parent_reltype = InvalidOid; // parentRel->rd_rel->reltype;
+ appinfo.child_relid = -1;
+ appinfo.child_reltype = InvalidOid; // partrel->rd_rel->reltype;
+ appinfo.parent_reloid = 1; // dummy parentRel->rd_id;
+ make_inh_translation_list(parentDesc, partitionDesc, partitionRelname,
+ 1, /* dummy */
+ &appinfo.translated_vars);
+ result_tl = adjust_inherited_tlist((List *) targetlist, &appinfo);
+
+ /*
+ * Add any attributes that are missing in the source list, such
+ * as dropped columns in the partition.
+ */
+ result_tl = expand_targetlist(result_tl, CMD_UPDATE,
+ parentVarno, partitionDesc);
+
+ return result_tl;
+}
+
+/*
* adjust_appendrel_attrs_multilevel
* Apply Var translations from a toplevel appendrel parent down to a child.
*
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index d380b419d7..c5263f65dc 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -14,6 +14,7 @@
#ifndef PREP_H
#define PREP_H
+#include "access/tupdesc.h"
#include "nodes/plannodes.h"
#include "nodes/relation.h"
@@ -42,9 +43,8 @@ extern List *preprocess_targetlist(PlannerInfo *root);
extern PlanRowMark *get_plan_rowmark(List *rowmarks, Index rtindex);
-typedef struct RelationData *Relation;
extern List *expand_targetlist(List *tlist, int command_type,
- Index result_relation, Relation rel);
+ Index result_relation, TupleDesc tupdesc);
/*
* prototypes for prepunion.c
@@ -69,11 +69,10 @@ extern SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
extern Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids,
Relids child_relids, Relids top_parent_relids);
-extern void make_inh_translation_list(Relation oldrelation,
- Relation newrelation,
- Index newvarno,
- List **translated_vars);
-extern List *adjust_inherited_tlist(List *tlist,
- AppendRelInfo *context);
+extern List *adjust_and_expand_partition_tlist(TupleDesc parentDesc,
+ TupleDesc partitionDesc,
+ char *partitionRelname,
+ int parentVarno,
+ List *targetlist);
#endif /* PREP_H */
--
2.11.0
--l3nzpdtx3xgmrx2w--
view thread (10+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v3 3/3] fixups
In-Reply-To: <no-message-id-791783@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox