@@ -37,7 +37,6 @@ typedef struct
37
37
#define IsPlusInfinity (i ) ( (i)->is_infinite == PLUS_INFINITY )
38
38
#define IsMinusInfinity (i ) ( (i)->is_infinite == MINUS_INFINITY )
39
39
40
-
41
40
static inline Bound
42
41
CopyBound (const Bound * src , bool byval , int typlen )
43
42
{
@@ -75,6 +74,13 @@ BoundGetValue(const Bound *bound)
75
74
return bound -> value ;
76
75
}
77
76
77
+ static inline void
78
+ FreeBound (Bound * bound , bool byval )
79
+ {
80
+ if (!IsInfinite (bound ) && !byval )
81
+ pfree (DatumGetPointer (BoundGetValue (bound )));
82
+ }
83
+
78
84
static inline int
79
85
cmp_bounds (FmgrInfo * cmp_func , const Bound * b1 , const Bound * b2 )
80
86
{
@@ -97,7 +103,7 @@ cmp_bounds(FmgrInfo *cmp_func, const Bound *b1, const Bound *b2)
97
103
*/
98
104
typedef enum
99
105
{
100
- PT_INDIFFERENT = 0 , /* for part type traits (virtual type) */
106
+ PT_ANY = 0 , /* for part type traits (virtual type) */
101
107
PT_HASH ,
102
108
PT_RANGE
103
109
} PartType ;
@@ -122,11 +128,14 @@ typedef struct
122
128
bool valid ; /* is this entry valid? */
123
129
bool enable_parent ; /* include parent to the plan */
124
130
131
+ PartType parttype ; /* partitioning type (HASH | RANGE) */
132
+
125
133
uint32 children_count ;
126
134
Oid * children ; /* Oids of child partitions */
127
135
RangeEntry * ranges ; /* per-partition range entry or NULL */
128
136
129
- PartType parttype ; /* partitioning type (HASH | RANGE) */
137
+ const char * attname ; /* name of the partitioned column */
138
+
130
139
AttrNumber attnum ; /* partitioned column's index */
131
140
Oid atttype ; /* partitioned column's type */
132
141
int32 atttypmod ; /* partitioned column type modifier */
@@ -140,7 +149,7 @@ typedef struct
140
149
} PartRelationInfo ;
141
150
142
151
/*
143
- * RelParentInfo
152
+ * PartParentInfo
144
153
* Cached parent of the specified partition.
145
154
* Allows us to quickly search for PartRelationInfo.
146
155
*/
@@ -150,12 +159,24 @@ typedef struct
150
159
Oid parent_rel ;
151
160
} PartParentInfo ;
152
161
162
+ /*
163
+ * PartBoundInfo
164
+ * Cached bounds of the specified partition.
165
+ */
153
166
typedef struct
154
167
{
155
168
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 ;
159
180
160
181
/*
161
182
* PartParentSearch
@@ -220,38 +241,50 @@ void cache_parent_of_partition(Oid partition, Oid parent);
220
241
Oid forget_parent_of_partition (Oid partition , PartParentSearch * status );
221
242
Oid get_parent_of_partition (Oid partition , PartParentSearch * status );
222
243
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 );
226
248
227
249
/* Safe casts for PartType */
228
250
PartType DatumGetPartType (Datum datum );
229
251
char * PartTypeToCString (PartType parttype );
230
252
231
253
/* PartRelationInfo checker */
232
- void shout_if_prel_is_invalid (Oid parent_oid ,
254
+ void shout_if_prel_is_invalid (const Oid parent_oid ,
233
255
const PartRelationInfo * prel ,
234
- PartType expected_part_type );
256
+ const PartType expected_part_type );
235
257
236
258
237
259
/*
238
- * Useful static functions for freeing memory.
260
+ * Useful functions & macros for freeing memory.
239
261
*/
240
262
263
+ #define FreeIfNotNull (ptr ) \
264
+ do { \
265
+ if (ptr) \
266
+ { \
267
+ pfree((void *) ptr); \
268
+ ptr = NULL; \
269
+ } \
270
+ } while(0)
271
+
241
272
static inline void
242
273
FreeChildrenArray (PartRelationInfo * prel )
243
274
{
244
275
uint32 i ;
245
276
246
- Assert (PrelIsValid (prel ));
247
-
248
277
/* Remove relevant PartParentInfos */
249
278
if (prel -> children )
250
279
{
251
280
for (i = 0 ; i < PrelChildrenCount (prel ); i ++ )
252
281
{
253
282
Oid child = prel -> children [i ];
254
283
284
+ /* Skip if Oid is invalid (e.g. initialization error) */
285
+ if (!OidIsValid (child ))
286
+ continue ;
287
+
255
288
/* If it's *always been* relid's partition, free cache */
256
289
if (PrelParentRelid (prel ) == get_parent_of_partition (child , NULL ))
257
290
forget_parent_of_partition (child , NULL );
@@ -267,8 +300,6 @@ FreeRangesArray(PartRelationInfo *prel)
267
300
{
268
301
uint32 i ;
269
302
270
- Assert (PrelIsValid (prel ));
271
-
272
303
/* Remove RangeEntries array */
273
304
if (prel -> ranges )
274
305
{
@@ -277,11 +308,14 @@ FreeRangesArray(PartRelationInfo *prel)
277
308
{
278
309
for (i = 0 ; i < PrelChildrenCount (prel ); i ++ )
279
310
{
280
- if (!IsInfinite (& prel -> ranges [i ].min ))
281
- pfree (DatumGetPointer (BoundGetValue (& prel -> ranges [i ].min )));
311
+ Oid child = prel -> ranges [i ].child_oid ;
282
312
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 );
285
319
}
286
320
}
287
321
@@ -290,5 +324,4 @@ FreeRangesArray(PartRelationInfo *prel)
290
324
}
291
325
}
292
326
293
-
294
327
#endif /* RELATION_INFO_H */
0 commit comments