Skip to content

Commit f85232a

Browse files
committed
refactoring (move functions, renames and fixes), use bounds cache instead of constraints cache, introduce macro AssertTemporaryContext()
1 parent 20fbd32 commit f85232a

File tree

8 files changed

+451
-319
lines changed

8 files changed

+451
-319
lines changed

src/hooks.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,8 @@ pathman_relcache_hook(Datum arg, Oid relid)
624624
if (relid == get_pathman_config_relid(false))
625625
delay_pathman_shutdown();
626626

627-
/* Invalidate PartConstraintInfo cache if needed */
628-
forget_constraint_of_partition(relid);
627+
/* Invalidate PartBoundInfo cache if needed */
628+
forget_bounds_of_partition(relid);
629629

630630
/* Invalidate PartParentInfo cache if needed */
631631
partitioned_table = forget_parent_of_partition(relid, &search);

src/include/init.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,26 @@ typedef struct
3737
} PathmanInitState;
3838

3939

40+
/* Check that this is a temporary memory context that's going to be destroyed */
41+
#define AssertTemporaryContext() \
42+
do { \
43+
Assert(CurrentMemoryContext != TopMemoryContext); \
44+
Assert(CurrentMemoryContext != TopPathmanContext); \
45+
Assert(CurrentMemoryContext != PathmanRelationCacheContext); \
46+
Assert(CurrentMemoryContext != PathmanParentCacheContext); \
47+
Assert(CurrentMemoryContext != PathmanBoundCacheContext); \
48+
} while (0)
49+
50+
4051
#define PATHMAN_MCXT_COUNT 4
4152
extern MemoryContext TopPathmanContext;
4253
extern MemoryContext PathmanRelationCacheContext;
4354
extern MemoryContext PathmanParentCacheContext;
44-
extern MemoryContext PathmanCostraintCacheContext;
55+
extern MemoryContext PathmanBoundCacheContext;
4556

4657
extern HTAB *partitioned_rels;
4758
extern HTAB *parent_cache;
48-
extern HTAB *constraint_cache;
59+
extern HTAB *bound_cache;
4960

5061
/* pg_pathman's initialization state */
5162
extern PathmanInitState pg_pathman_init_state;
@@ -55,10 +66,10 @@ extern PathmanInitState pg_pathman_init_state;
5566
static inline const char *
5667
simpify_mcxt_name(MemoryContext mcxt)
5768
{
58-
static const char *top_mcxt = "maintenance";
59-
static const char *bound_mcxt = "bounds cache";
60-
static const char *parent_mcxt = "parents cache";
61-
static const char *constr_mcxt = "constraints cache";
69+
static const char *top_mcxt = "maintenance",
70+
*bound_mcxt = "partition info cache",
71+
*parent_mcxt = "parent mapping cache",
72+
*constr_mcxt = "bounds cache";
6273

6374
if (mcxt == TopPathmanContext)
6475
return top_mcxt;
@@ -69,7 +80,7 @@ simpify_mcxt_name(MemoryContext mcxt)
6980
else if (mcxt == PathmanParentCacheContext)
7081
return parent_mcxt;
7182

72-
else if (mcxt == PathmanCostraintCacheContext)
83+
else if (mcxt == PathmanBoundCacheContext)
7384
return constr_mcxt;
7485

7586
else elog(ERROR, "error in function " CppAsString(simpify_mcxt_name));
@@ -166,11 +177,6 @@ bool load_config(void);
166177
void unload_config(void);
167178

168179

169-
void fill_prel_with_partitions(const Oid *partitions,
170-
const uint32 parts_count,
171-
const char *part_column_name,
172-
PartRelationInfo *prel);
173-
174180
/* Result of find_inheritance_children_array() */
175181
typedef enum
176182
{
@@ -203,4 +209,16 @@ bool read_pathman_params(Oid relid,
203209
bool *isnull);
204210

205211

212+
bool validate_range_constraint(const Expr *expr,
213+
const PartRelationInfo *prel,
214+
const AttrNumber part_attno,
215+
Datum *lower, Datum *upper,
216+
bool *lower_null, bool *upper_null);
217+
218+
bool validate_hash_constraint(const Expr *expr,
219+
const PartRelationInfo *prel,
220+
const AttrNumber part_attno,
221+
uint32 *part_hash);
222+
223+
206224
#endif /* PATHMAN_INIT_H */

src/include/relation_info.h

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ typedef struct
3737
#define IsPlusInfinity(i) ( (i)->is_infinite == PLUS_INFINITY )
3838
#define IsMinusInfinity(i) ( (i)->is_infinite == MINUS_INFINITY )
3939

40-
4140
static inline Bound
4241
CopyBound(const Bound *src, bool byval, int typlen)
4342
{
@@ -75,6 +74,13 @@ BoundGetValue(const Bound *bound)
7574
return bound->value;
7675
}
7776

77+
static inline void
78+
FreeBound(Bound *bound, bool byval)
79+
{
80+
if (!IsInfinite(bound) && !byval)
81+
pfree(DatumGetPointer(BoundGetValue(bound)));
82+
}
83+
7884
static inline int
7985
cmp_bounds(FmgrInfo *cmp_func, const Bound *b1, const Bound *b2)
8086
{
@@ -97,7 +103,7 @@ cmp_bounds(FmgrInfo *cmp_func, const Bound *b1, const Bound *b2)
97103
*/
98104
typedef enum
99105
{
100-
PT_INDIFFERENT = 0, /* for part type traits (virtual type) */
106+
PT_ANY = 0, /* for part type traits (virtual type) */
101107
PT_HASH,
102108
PT_RANGE
103109
} PartType;
@@ -122,11 +128,14 @@ typedef struct
122128
bool valid; /* is this entry valid? */
123129
bool enable_parent; /* include parent to the plan */
124130

131+
PartType parttype; /* partitioning type (HASH | RANGE) */
132+
125133
uint32 children_count;
126134
Oid *children; /* Oids of child partitions */
127135
RangeEntry *ranges; /* per-partition range entry or NULL */
128136

129-
PartType parttype; /* partitioning type (HASH | RANGE) */
137+
const char *attname; /* name of the partitioned column */
138+
130139
AttrNumber attnum; /* partitioned column's index */
131140
Oid atttype; /* partitioned column's type */
132141
int32 atttypmod; /* partitioned column type modifier */
@@ -140,7 +149,7 @@ typedef struct
140149
} PartRelationInfo;
141150

142151
/*
143-
* RelParentInfo
152+
* PartParentInfo
144153
* Cached parent of the specified partition.
145154
* Allows us to quickly search for PartRelationInfo.
146155
*/
@@ -150,12 +159,24 @@ typedef struct
150159
Oid parent_rel;
151160
} PartParentInfo;
152161

162+
/*
163+
* PartBoundInfo
164+
* Cached bounds of the specified partition.
165+
*/
153166
typedef struct
154167
{
155168
Oid child_rel; /* key */
156-
Oid conid;
157-
Expr *constraint;
158-
} PartConstraintInfo;
169+
170+
PartType parttype;
171+
172+
/* For RANGE partitions */
173+
Bound range_min;
174+
Bound range_max;
175+
bool byval;
176+
177+
/* For HASH partitions */
178+
uint32 hash;
179+
} PartBoundInfo;
159180

160181
/*
161182
* PartParentSearch
@@ -220,38 +241,50 @@ void cache_parent_of_partition(Oid partition, Oid parent);
220241
Oid forget_parent_of_partition(Oid partition, PartParentSearch *status);
221242
Oid get_parent_of_partition(Oid partition, PartParentSearch *status);
222243

223-
/* Constraint cache */
224-
void forget_constraint_of_partition(Oid partition);
225-
Expr * get_constraint_of_partition(Oid partition, AttrNumber part_attno);
244+
/* Bounds cache */
245+
void forget_bounds_of_partition(Oid partition);
246+
PartBoundInfo * get_bounds_of_partition(Oid partition,
247+
const PartRelationInfo *prel);
226248

227249
/* Safe casts for PartType */
228250
PartType DatumGetPartType(Datum datum);
229251
char * PartTypeToCString(PartType parttype);
230252

231253
/* PartRelationInfo checker */
232-
void shout_if_prel_is_invalid(Oid parent_oid,
254+
void shout_if_prel_is_invalid(const Oid parent_oid,
233255
const PartRelationInfo *prel,
234-
PartType expected_part_type);
256+
const PartType expected_part_type);
235257

236258

237259
/*
238-
* Useful static functions for freeing memory.
260+
* Useful functions & macros for freeing memory.
239261
*/
240262

263+
#define FreeIfNotNull(ptr) \
264+
do { \
265+
if (ptr) \
266+
{ \
267+
pfree((void *) ptr); \
268+
ptr = NULL; \
269+
} \
270+
} while(0)
271+
241272
static inline void
242273
FreeChildrenArray(PartRelationInfo *prel)
243274
{
244275
uint32 i;
245276

246-
Assert(PrelIsValid(prel));
247-
248277
/* Remove relevant PartParentInfos */
249278
if (prel->children)
250279
{
251280
for (i = 0; i < PrelChildrenCount(prel); i++)
252281
{
253282
Oid child = prel->children[i];
254283

284+
/* Skip if Oid is invalid (e.g. initialization error) */
285+
if (!OidIsValid(child))
286+
continue;
287+
255288
/* If it's *always been* relid's partition, free cache */
256289
if (PrelParentRelid(prel) == get_parent_of_partition(child, NULL))
257290
forget_parent_of_partition(child, NULL);
@@ -267,8 +300,6 @@ FreeRangesArray(PartRelationInfo *prel)
267300
{
268301
uint32 i;
269302

270-
Assert(PrelIsValid(prel));
271-
272303
/* Remove RangeEntries array */
273304
if (prel->ranges)
274305
{
@@ -277,11 +308,14 @@ FreeRangesArray(PartRelationInfo *prel)
277308
{
278309
for (i = 0; i < PrelChildrenCount(prel); i++)
279310
{
280-
if (!IsInfinite(&prel->ranges[i].min))
281-
pfree(DatumGetPointer(BoundGetValue(&prel->ranges[i].min)));
311+
Oid child = prel->ranges[i].child_oid;
282312

283-
if (!IsInfinite(&prel->ranges[i].max))
284-
pfree(DatumGetPointer(BoundGetValue(&prel->ranges[i].max)));
313+
/* Skip if Oid is invalid (e.g. initialization error) */
314+
if (!OidIsValid(child))
315+
continue;
316+
317+
FreeBound(&prel->ranges[i].min, prel->attbyval);
318+
FreeBound(&prel->ranges[i].max, prel->attbyval);
285319
}
286320
}
287321

@@ -290,5 +324,4 @@ FreeRangesArray(PartRelationInfo *prel)
290324
}
291325
}
292326

293-
294327
#endif /* RELATION_INFO_H */

0 commit comments

Comments
 (0)