提交 b22544fb 编写于 作者: H Heikki Linnakangas

Clean up the internal functions to merge partition stats a bit.

aggregate_leaf_partition_MCVs() and aggregate_leaf_partition_histograms()
functions did catalog lookups to count how many leaf partitions a root
table has. Why? Because the caller passes two arrays as inputs, with an
entry for each partition, and the functions need to know how large the
input arrays are. That's overly complicated, of course: the caller can
simply pass the size of the arrays as an argument. That's much more robust
too, I think the current code would crash and burn if the partition
hierarchy was modified concurrently. I'm not sure if that's a live bug, or
if we're holding locks that prevent that, but let's keep things simple in
any case.

This removes the last callers of rel_get_leaf_children_relids() function,
so remove that altogether.
Reviewed-by: NAbhijit Subramanya <asubramanya@pivotal.io>
Reviewed-by: NHans Zeller <hzeller@vmware.com>
上级 40443808
......@@ -219,7 +219,6 @@ static char *ChooseConstraintNameForPartitionCreate(const char *rname,
static Bitmapset *get_partition_key_bitmapset(Oid relid);
static List *get_deparsed_partition_encodings(Oid relid, Oid paroid);
static List *rel_get_leaf_relids_from_rule(Oid ruleOid);
/*
* Is the given relation the default partition of a partition table.
......@@ -3154,128 +3153,6 @@ all_leaf_partition_relids(PartitionNode *pn)
return leaf_relids;
}
/*
* Given an Oid of a partition rule, return all leaf-level table Oids that are
* descendants of the given rule.
* Input:
* ruleOid - the oid of an entry in pg_partition_rule
* Output:
* a list of Oids of all leaf-level partition tables under the given rule in
* the partitioning hierarchy.
*/
static List *
rel_get_leaf_relids_from_rule(Oid ruleOid)
{
ScanKeyData scankey;
Relation part_rule_rel;
SysScanDesc sscan;
bool hasChildren = false;
List *lChildrenOid = NIL;
HeapTuple tuple;
if (!OidIsValid(ruleOid))
{
return NIL;
}
part_rule_rel = heap_open(PartitionRuleRelationId, AccessShareLock);
ScanKeyInit(&scankey, Anum_pg_partition_rule_parparentrule,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(ruleOid));
/* No suitable index */
sscan = systable_beginscan(part_rule_rel, InvalidOid, false,
NULL, 1, &scankey);
/*
* If we are still in mid-level, recursively call this function on
* children rules of the given rule.
*/
while ((tuple = systable_getnext(sscan)) != NULL)
{
hasChildren = true;
lChildrenOid = list_concat(lChildrenOid, rel_get_leaf_relids_from_rule(HeapTupleGetOid(tuple)));
}
/*
* if ruleOid is not parent of any rule, we have reached the leaf level
* and we need to append parchildrelid of this entry to the output
*/
if (!hasChildren)
{
HeapTuple tuple;
Form_pg_partition_rule rule_desc;
tuple = SearchSysCache1(PARTRULEOID, ObjectIdGetDatum(ruleOid));
if (!tuple)
elog(ERROR, "cache lookup failed for partition rule with OID %u", ruleOid);
rule_desc = (Form_pg_partition_rule) GETSTRUCT(tuple);
lChildrenOid = lcons_oid(rule_desc->parchildrelid, lChildrenOid);
ReleaseSysCache(tuple);
}
systable_endscan(sscan);
heap_close(part_rule_rel, AccessShareLock);
return lChildrenOid;
}
/* Given a partition table Oid (root or interior), return the Oids of all leaf-level
* children below it. Similar to all_leaf_partition_relids() but takes Oid as input.
*/
List *
rel_get_leaf_children_relids(Oid relid)
{
PartStatus ps = rel_part_status(relid);
List *leaf_relids = NIL;
Assert(PART_STATUS_INTERIOR == ps || PART_STATUS_ROOT == ps);
if (PART_STATUS_ROOT == ps)
{
PartitionNode *pn;
pn = get_parts(relid, 0 /* level */ , 0 /* parent */ , false /* inctemplate */ ,
true /* includesubparts */ );
leaf_relids = all_leaf_partition_relids(pn);
pfree(pn);
}
else if (PART_STATUS_INTERIOR == ps)
{
Relation partrulerel;
ScanKeyData scankey;
SysScanDesc sscan;
HeapTuple tuple;
/* SELECT * FROM pg_partition_rule WHERE parchildrelid = :1 */
partrulerel = heap_open(PartitionRuleRelationId, AccessShareLock);
ScanKeyInit(&scankey, Anum_pg_partition_rule_parchildrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relid));
sscan = systable_beginscan(partrulerel, PartitionRuleParchildrelidIndexId, true,
NULL, 1, &scankey);
tuple = systable_getnext(sscan);
if (HeapTupleIsValid(tuple))
{
leaf_relids = rel_get_leaf_relids_from_rule(HeapTupleGetOid(tuple));
}
systable_endscan(sscan);
heap_close(partrulerel, AccessShareLock);
}
else if (PART_STATUS_LEAF == ps)
{
leaf_relids = list_make1_oid(relid);
}
return leaf_relids;
}
/* Return the pg_class Oids of the relations representing interior parts of the
* PartitionNode tree headed by the argument PartitionNode.
*
......
......@@ -4423,8 +4423,9 @@ merge_leaf_stats(VacAttrStatsP stats,
void *resultMCV[2];
mcvpairArray = aggregate_leaf_partition_MCVs(
stats->attr->attrelid, stats->attr->attnum, heaptupleStats,
relTuples, default_statistics_target, ndistinct, &num_mcv, &rem_mcv,
stats->attr->attrelid, stats->attr->attnum,
numPartitions, heaptupleStats, relTuples,
default_statistics_target, ndistinct, &num_mcv, &rem_mcv,
resultMCV);
MemoryContextSwitchTo(old_context);
......@@ -4447,8 +4448,9 @@ merge_leaf_stats(VacAttrStatsP stats,
void *resultHistogram[1];
int num_hist = aggregate_leaf_partition_histograms(
stats->attr->attrelid, stats->attr->attnum, heaptupleStats,
relTuples, default_statistics_target, mcvpairArray + num_mcv,
stats->attr->attrelid, stats->attr->attnum,
numPartitions, heaptupleStats, relTuples,
default_statistics_target, mcvpairArray + num_mcv,
rem_mcv, resultHistogram);
MemoryContextSwitchTo(old_context);
if (num_hist > 0)
......
......@@ -141,17 +141,23 @@ addLeafPartitionMCVsToHashTable (HTAB *datumHash, HeapTuple heaptupleStats,
/*
* Main function for aggregating leaf partition MCV/Freq to compute
* root or interior partition MCV/Freq
*
* Input:
* - relationOid: Oid of root or interior partition
* - attnum: column number
* - numPartitions: # of elements in heaptupleStats and relTuples arrays
* - heaptupleStats: pg_statistics tuples for each partition
* - relTuples: number of tuples in each partition (pg_class.reltuples)
* - nEntries: target number of MCVs/Freqs to be collected, the real number of
* MCVs/Freqs returned may be less
*
* Output:
* - result: two dimensional arrays of MCVs and Freqs
*/
MCVFreqPair **
aggregate_leaf_partition_MCVs(Oid relationOid,
AttrNumber attnum,
int numPartitions,
HeapTuple *heaptupleStats,
float4 *relTuples,
unsigned int nEntries,
......@@ -160,8 +166,6 @@ aggregate_leaf_partition_MCVs(Oid relationOid,
int *rem_mcv,
void **result)
{
List *lRelOids = rel_get_leaf_children_relids(relationOid); /* list of OIDs of leaf
* partitions */
Oid typoid = get_atttype(relationOid, attnum);
TypInfo *typInfo = (TypInfo *) palloc(sizeof(TypInfo));
......@@ -171,8 +175,6 @@ aggregate_leaf_partition_MCVs(Oid relationOid,
HTAB *datumHash = createDatumHashTable(nEntries);
float4 sumReltuples = 0;
int numPartitions = list_length(lRelOids);
for (int i = 0; i < numPartitions; i++)
{
if (!HeapTupleIsValid(heaptupleStats[i]))
......@@ -759,6 +761,8 @@ datumCompare(Datum d1, Datum d2, Oid opFuncOid)
* Input:
* - relationOid: Oid of root or interior partition
* - attnum: column number
* - nParts: # of elements in heaptupleStats and relTuples arrays
* - heaptupleStats: pg_statistics tuples for each partition
* - nEntries: target number of histogram bounds to be collected, the real number of
* histogram bounds returned may be less
* Output:
......@@ -819,6 +823,7 @@ datumCompare(Datum d1, Datum d2, Oid opFuncOid)
int
aggregate_leaf_partition_histograms(Oid relationOid,
AttrNumber attnum,
int nParts,
HeapTuple *heaptupleStats,
float4 *relTuples,
unsigned int nEntries,
......@@ -827,10 +832,6 @@ aggregate_leaf_partition_histograms(Oid relationOid,
void **result)
{
AssertImply(rem_mcv != 0, mcvpairArray != NULL);
List *lRelOids = rel_get_leaf_children_relids(relationOid);
int nParts = list_length(lRelOids);
Assert(nParts > 0);
/* get type information */
......
......@@ -125,9 +125,6 @@ extern PartitionNode *RelationBuildPartitionDesc(Relation rel,
extern PartitionNode *RelationBuildPartitionDescByOid(Oid relid,
bool inctemplate);
extern List *
rel_get_leaf_children_relids(Oid relid);
extern Oid
rel_partition_get_root(Oid relid);
......
......@@ -35,6 +35,7 @@ typedef struct MCVFreqPair
/* extern functions called by commands/analyze.c */
extern MCVFreqPair **aggregate_leaf_partition_MCVs(Oid relationOid,
AttrNumber attnum,
int numPartitions,
HeapTuple *heaptupleStats,
float4 *relTuples,
unsigned int nEntries,
......@@ -47,6 +48,7 @@ extern float4 get_rel_reltuples(Oid relid);
extern int32 get_rel_relpages(Oid relid);
extern int aggregate_leaf_partition_histograms(Oid relationOid,
AttrNumber attnum,
int nParts,
HeapTuple *heaptupleStats,
float4 *relTuples,
unsigned int nEntries,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册