Skip to content

Commit 3e546d8

Browse files
committed
pathman: use compound key (dbid + relid) for hash tables
1 parent 035889a commit 3e546d8

File tree

4 files changed

+73
-47
lines changed

4 files changed

+73
-47
lines changed

contrib/pg_pathman/init.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "pathman.h"
2+
#include "miscadmin.h"
23
#include "executor/spi.h"
34
#include "catalog/pg_type.h"
45
#include "catalog/pg_class.h"
@@ -108,12 +109,15 @@ load_relations_hashtable(bool reinitialize)
108109

109110
for (i=0; i<proc; i++)
110111
{
112+
RelationKey key;
111113
HeapTuple tuple = tuptable->vals[i];
112114
int oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 1, &isnull));
113115

116+
key.dbid = MyDatabaseId;
117+
key.relid = oid;
114118
prel = (PartRelationInfo*)
115-
hash_search(relations, (const void *)&oid, HASH_ENTER, NULL);
116-
prel->oid = oid;
119+
hash_search(relations, (const void *) &key, HASH_ENTER, NULL);
120+
117121
prel->attnum = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 2, &isnull));
118122
prel->parttype = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 3, &isnull));
119123
prel->atttype = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 4, &isnull));
@@ -128,16 +132,13 @@ load_relations_hashtable(bool reinitialize)
128132
{
129133
Oid oid = (int) lfirst_int(lc);
130134

131-
prel = (PartRelationInfo*)
132-
hash_search(relations, (const void *)&oid, HASH_FIND, NULL);
133-
135+
prel = get_pathman_relation_info(oid, NULL);
134136
switch(prel->parttype)
135137
{
136138
case PT_RANGE:
137139
if (reinitialize && prel->children.length > 0)
138140
{
139-
RangeRelation *rangerel = (RangeRelation *)
140-
hash_search(range_restrictions, (void *) &oid, HASH_FIND, NULL);
141+
RangeRelation *rangerel = get_pathman_range_relation(oid, NULL);
141142
free_dsm_array(&prel->children);
142143
free_dsm_array(&rangerel->ranges);
143144
prel->children_count = 0;
@@ -163,14 +164,14 @@ create_relations_hashtable()
163164
HASHCTL ctl;
164165

165166
memset(&ctl, 0, sizeof(ctl));
166-
ctl.keysize = sizeof(int);
167+
ctl.keysize = sizeof(RelationKey);
167168
ctl.entrysize = sizeof(PartRelationInfo);
168169

169170
/* Already exists, recreate */
170171
if (relations != NULL)
171172
hash_destroy(relations);
172173

173-
relations = ShmemInitHash("Partitioning relation info", 1024, &ctl, HASH_ELEM);
174+
relations = ShmemInitHash("Partitioning relation info", 1024, &ctl, HASH_ELEM | HASH_BLOBS);
174175
}
175176

176177
/*
@@ -191,8 +192,7 @@ load_check_constraints(Oid parent_oid)
191192
bool nulls[1] = {false};
192193
vals[0] = Int32GetDatum(parent_oid);
193194

194-
prel = (PartRelationInfo*)
195-
hash_search(relations, (const void *) &parent_oid, HASH_FIND, &found);
195+
prel = get_pathman_relation_info(parent_oid, NULL);
196196

197197
/* Skip if already loaded */
198198
if (prel->children.length > 0)
@@ -219,8 +219,12 @@ load_check_constraints(Oid parent_oid)
219219

220220
if (prel->parttype == PT_RANGE)
221221
{
222+
RelationKey key;
223+
key.dbid = MyDatabaseId;
224+
key.relid = parent_oid;
225+
222226
rangerel = (RangeRelation *)
223-
hash_search(range_restrictions, (void *) &parent_oid, HASH_ENTER, &found);
227+
hash_search(range_restrictions, (void *) &key, HASH_ENTER, &found);
224228

225229
alloc_dsm_array(&rangerel->ranges, sizeof(RangeEntry), proc);
226230
ranges = (RangeEntry *) dsm_array_get_pointer(&rangerel->ranges);
@@ -297,9 +301,13 @@ load_check_constraints(Oid parent_oid)
297301
{
298302
if (ranges[i].max > ranges[i+1].min)
299303
{
304+
RelationKey key;
305+
key.dbid = MyDatabaseId;
306+
key.relid = parent_oid;
307+
300308
elog(WARNING, "Partitions %u and %u overlap. Disabling pathman for relation %u...",
301309
ranges[i].child_oid, ranges[i+1].child_oid, parent_oid);
302-
hash_search(relations, (const void *) &parent_oid, HASH_REMOVE, &found);
310+
hash_search(relations, (const void *) &key, HASH_REMOVE, &found);
303311
}
304312
}
305313
}
@@ -433,7 +441,7 @@ create_range_restrictions_hashtable()
433441
HASHCTL ctl;
434442

435443
memset(&ctl, 0, sizeof(ctl));
436-
ctl.keysize = sizeof(int);
444+
ctl.keysize = sizeof(RelationKey);
437445
ctl.entrysize = sizeof(RangeRelation);
438446
range_restrictions = ShmemInitHash("pg_pathman range restrictions",
439447
1024, &ctl, HASH_ELEM | HASH_BLOBS);
@@ -447,9 +455,12 @@ remove_relation_info(Oid relid)
447455
{
448456
PartRelationInfo *prel;
449457
RangeRelation *rangerel;
458+
RelationKey key;
459+
460+
key.dbid = MyDatabaseId;
461+
key.relid = relid;
450462

451-
prel = (PartRelationInfo *)
452-
hash_search(relations, (const void *) &relid, HASH_FIND, 0);
463+
prel = get_pathman_relation_info(relid, NULL);
453464

454465
/* If there is nothing to remove then just return */
455466
if (!prel)
@@ -462,11 +473,10 @@ remove_relation_info(Oid relid)
462473
free_dsm_array(&prel->children);
463474
break;
464475
case PT_RANGE:
465-
rangerel = (RangeRelation *)
466-
hash_search(range_restrictions, (const void *) &relid, HASH_FIND, 0);
476+
rangerel = get_pathman_range_relation(relid, NULL);
467477
free_dsm_array(&rangerel->ranges);
468478
free_dsm_array(&prel->children);
469-
hash_search(range_restrictions, (const void *) &relid, HASH_REMOVE, 0);
479+
hash_search(range_restrictions, (const void *) &key, HASH_REMOVE, 0);
470480
break;
471481
}
472482
prel->children_count = 0;

contrib/pg_pathman/pathman.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ typedef struct DsmArray
3131
size_t length;
3232
} DsmArray;
3333

34+
/*
35+
* Hashtable key for relations
36+
*/
37+
typedef struct RelationKey
38+
{
39+
Oid dbid;
40+
Oid relid;
41+
} RelationKey;
42+
3443
/*
3544
* PartRelationInfo
3645
* Per-relation partitioning information
@@ -42,8 +51,8 @@ typedef struct DsmArray
4251
*/
4352
typedef struct PartRelationInfo
4453
{
45-
Oid oid;
46-
DsmArray children;
54+
RelationKey key;
55+
DsmArray children;
4756
int children_count;
4857
PartType parttype;
4958
Index attnum;
@@ -78,7 +87,7 @@ typedef struct RangeEntry
7887

7988
typedef struct RangeRelation
8089
{
81-
Oid parent_oid;
90+
RelationKey key;
8291
DsmArray ranges;
8392
} RangeRelation;
8493

@@ -143,6 +152,8 @@ void load_check_constraints(Oid parent_oid);
143152
void remove_relation_info(Oid relid);
144153

145154
/* utility functions */
155+
PartRelationInfo *get_pathman_relation_info(Oid relid, bool *found);
156+
RangeRelation *get_pathman_range_relation(Oid relid, bool *found);
146157
int range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum value, bool *fountPtr);
147158

148159
#endif /* PATHMAN_H */

contrib/pg_pathman/pg_pathman.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,26 @@ _PG_fini(void)
127127
planner_hook = planner_hook_original;
128128
}
129129

130+
PartRelationInfo *
131+
get_pathman_relation_info(Oid relid, bool *found)
132+
{
133+
RelationKey key;
134+
135+
key.dbid = MyDatabaseId;
136+
key.relid = relid;
137+
return hash_search(relations, (const void *) &key, HASH_FIND, found);
138+
}
139+
140+
RangeRelation *
141+
get_pathman_range_relation(Oid relid, bool *found)
142+
{
143+
RelationKey key;
144+
145+
key.dbid = MyDatabaseId;
146+
key.relid = relid;
147+
return hash_search(range_restrictions, (const void *) &key, HASH_FIND, found);
148+
}
149+
130150
/*
131151
* Planner hook. It disables inheritance for tables that have been partitioned
132152
* by pathman to prevent standart PostgreSQL partitioning mechanism from
@@ -174,8 +194,7 @@ disable_inheritance(Query *parse)
174194
if (rte->inh)
175195
{
176196
/* Look up this relation in pathman relations */
177-
prel = (PartRelationInfo *)
178-
hash_search(relations, (const void *) &rte->relid, HASH_FIND, 0);
197+
prel = get_pathman_relation_info(rte->relid, NULL);
179198
if (prel != NULL)
180199
{
181200
rte->inh = false;
@@ -240,8 +259,7 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
240259
return;
241260

242261
/* Lookup partitioning information for parent relation */
243-
prel = (PartRelationInfo *)
244-
hash_search(relations, (const void *) &rte->relid, HASH_FIND, 0);
262+
prel = get_pathman_relation_info(rte->relid, NULL);
245263

246264
if (prel != NULL)
247265
{
@@ -649,8 +667,7 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
649667
}
650668
case PT_RANGE:
651669
value = c->constvalue;
652-
rangerel = (RangeRelation *)
653-
hash_search(range_restrictions, (const void *)&prel->oid, HASH_FIND, NULL);
670+
rangerel = get_pathman_range_relation(prel->key.relid, NULL);
654671
if (rangerel != NULL)
655672
{
656673
RangeEntry *re;
@@ -830,8 +847,6 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
830847
/* Check boundaries */
831848
cmp_min = FunctionCall2(cmp_func, value, ranges[0].min),
832849
cmp_max = FunctionCall2(cmp_func, value, ranges[rangerel->ranges.length - 1].max);
833-
// cmp_min = OidFunctionCall2(cmp_proc, value, ranges[0].min);
834-
// cmp_max = OidFunctionCall2(cmp_proc, value, ranges[rangerel->ranges.length - 1].max);
835850
if (cmp_min < 0 || cmp_max >0)
836851
{
837852
return i;
@@ -844,8 +859,6 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
844859
re = &ranges[i];
845860
cmp_min = FunctionCall2(cmp_func, value, re->min);
846861
cmp_max = FunctionCall2(cmp_func, value, re->max);
847-
// cmp_min = OidFunctionCall2(cmp_proc, value, re->min);
848-
// cmp_max = OidFunctionCall2(cmp_proc, value, re->max);
849862

850863
if (cmp_min >= 0 && cmp_max < 0)
851864
{

contrib/pg_pathman/pl_funcs.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ on_partitions_updated(PG_FUNCTION_ARGS)
3838

3939
/* Parent relation oid */
4040
relid = DatumGetInt32(PG_GETARG_DATUM(0));
41-
prel = (PartRelationInfo *)
42-
hash_search(relations, (const void *) &relid, HASH_FIND, 0);
41+
prel = get_pathman_relation_info(relid, NULL);
4342
if (prel != NULL)
4443
{
4544
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
@@ -89,17 +88,14 @@ find_range_partition(PG_FUNCTION_ARGS)
8988
TYPECACHE_EQ_OPR | TYPECACHE_LT_OPR | TYPECACHE_GT_OPR |
9089
TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);
9190

92-
prel = (PartRelationInfo *)
93-
hash_search(relations, (const void *) &relid, HASH_FIND, NULL);
94-
91+
prel = get_pathman_relation_info(relid, NULL);
9592
cmp_proc_oid = get_opfamily_proc(tce->btree_opf,
9693
value_type,
9794
prel->atttype,
9895
BTORDER_PROC);
9996
fmgr_info(cmp_proc_oid, &cmp_func);
10097

101-
rangerel = (RangeRelation *)
102-
hash_search(range_restrictions, (const void *) &relid, HASH_FIND, NULL);
98+
rangerel = get_pathman_range_relation(relid, NULL);
10399

104100
if (!rangerel)
105101
PG_RETURN_NULL();
@@ -135,11 +131,9 @@ get_partition_range(PG_FUNCTION_ARGS)
135131
TypeCacheEntry *tce;
136132
ArrayType *arr;
137133

138-
prel = (PartRelationInfo *)
139-
hash_search(relations, (const void *) &parent_oid, HASH_FIND, NULL);
134+
prel = get_pathman_relation_info(parent_oid, NULL);
140135

141-
rangerel = (RangeRelation *)
142-
hash_search(range_restrictions, (const void *) &parent_oid, HASH_FIND, NULL);
136+
rangerel = get_pathman_range_relation(parent_oid, NULL);
143137

144138
if (!prel || !rangerel)
145139
PG_RETURN_NULL();
@@ -189,11 +183,9 @@ get_range_by_idx(PG_FUNCTION_ARGS)
189183
Datum *elems;
190184
TypeCacheEntry *tce;
191185

192-
prel = (PartRelationInfo *)
193-
hash_search(relations, (const void *) &parent_oid, HASH_FIND, NULL);
186+
prel = get_pathman_relation_info(parent_oid, NULL);
194187

195-
rangerel = (RangeRelation *)
196-
hash_search(range_restrictions, (const void *) &parent_oid, HASH_FIND, NULL);
188+
rangerel = get_pathman_range_relation(parent_oid, NULL);
197189

198190
if (!prel || !rangerel || idx >= (int)rangerel->ranges.length)
199191
PG_RETURN_NULL();

0 commit comments

Comments
 (0)