@@ -64,6 +64,9 @@ get_extension_schema()
64
64
return NULL ;
65
65
}
66
66
67
+ /*
68
+ * Loads partitioned tables structure to hashtable
69
+ */
67
70
void
68
71
load_relations_hashtable (bool reinitialize )
69
72
{
@@ -85,14 +88,14 @@ load_relations_hashtable(bool reinitialize)
85
88
SPI_connect ();
86
89
schema = get_extension_schema ();
87
90
88
- /* if extension doesn 't exist then just quit */
91
+ /* If extension isn 't exist then just quit */
89
92
if (!schema )
90
93
{
91
94
SPI_finish ();
92
95
return ;
93
96
}
94
97
95
- /* put schema name to the query */
98
+ /* Put schema name to the query */
96
99
query = psprintf (sql , schema );
97
100
ret = SPI_exec (query , 0 );
98
101
proc = SPI_processed ;
@@ -115,27 +118,21 @@ load_relations_hashtable(bool reinitialize)
115
118
prel -> atttype = DatumGetObjectId (SPI_getbinval (tuple , tupdesc , 4 , & isnull ));
116
119
117
120
part_oids = lappend_int (part_oids , oid );
118
-
119
- /* children will be filled in later */
120
- // prinfo->children = NIL;
121
121
}
122
122
}
123
123
pfree (query );
124
124
125
- /* load children information */
125
+ /* Load children information */
126
126
foreach (lc , part_oids )
127
127
{
128
128
Oid oid = (int ) lfirst_int (lc );
129
129
130
130
prel = (PartRelationInfo * )
131
131
hash_search (relations , (const void * )& oid , HASH_FIND , NULL );
132
132
133
- // load_check_constraints(oid);
134
-
135
133
switch (prel -> parttype )
136
134
{
137
135
case PT_RANGE :
138
- // load_range_restrictions(oid);
139
136
if (reinitialize && prel -> children .length > 0 )
140
137
{
141
138
RangeRelation * rangerel = (RangeRelation * )
@@ -168,7 +165,7 @@ create_relations_hashtable()
168
165
ctl .keysize = sizeof (int );
169
166
ctl .entrysize = sizeof (PartRelationInfo );
170
167
171
- /* already exists, recreate */
168
+ /* Already exists, recreate */
172
169
if (relations != NULL )
173
170
hash_destroy (relations );
174
171
@@ -196,7 +193,7 @@ load_check_constraints(Oid parent_oid)
196
193
prel = (PartRelationInfo * )
197
194
hash_search (relations , (const void * ) & parent_oid , HASH_FIND , & found );
198
195
199
- /* skip if already loaded */
196
+ /* Skip if already loaded */
200
197
if (prel -> children .length > 0 )
201
198
return ;
202
199
@@ -237,8 +234,6 @@ load_check_constraints(Oid parent_oid)
237
234
char * conbin ;
238
235
Expr * expr ;
239
236
240
- // HeapTuple reltuple;
241
- // Form_pg_class pg_class_tuple;
242
237
Form_pg_constraint con ;
243
238
244
239
con = (Form_pg_constraint ) GETSTRUCT (tuple );
@@ -255,8 +250,12 @@ load_check_constraints(Oid parent_oid)
255
250
{
256
251
case PT_RANGE :
257
252
if (!validate_range_constraint (expr , prel , & min , & max ))
258
- /* TODO: elog() */
253
+ {
254
+ elog (WARNING , "Range constraint for relation %u MUST have exact format: "
255
+ "VARIABLE >= CONST AND VARIABLE < CONST. Skipping..." ,
256
+ (Oid ) con -> conrelid );
259
257
continue ;
258
+ }
260
259
261
260
re .child_oid = con -> conrelid ;
262
261
re .min = min ;
@@ -267,24 +266,37 @@ load_check_constraints(Oid parent_oid)
267
266
268
267
case PT_HASH :
269
268
if (!validate_hash_constraint (expr , prel , & hash ))
270
- /* TODO: elog() */
269
+ {
270
+ elog (WARNING , "Hash constraint for relation %u MUST have exact format: "
271
+ "VARIABLE %% CONST = CONST. Skipping..." ,
272
+ (Oid ) con -> conrelid );
271
273
continue ;
274
+ }
272
275
children [hash ] = con -> conrelid ;
273
276
}
274
277
}
275
278
prel -> children_count = proc ;
276
279
277
280
if (prel -> parttype == PT_RANGE )
278
281
{
279
- /* sort ascending */
282
+ /* Sort ascending */
280
283
qsort (ranges , proc , sizeof (RangeEntry ), cmp_range_entries );
281
284
282
- /* copy oids to prel */
285
+ /* Copy oids to prel */
283
286
for (i = 0 ; i < proc ; i ++ )
284
287
children [i ] = ranges [i ].child_oid ;
285
288
}
286
289
287
- /* TODO: check if some ranges overlap! */
290
+ /* Check if some ranges overlap */
291
+ for (i = 0 ; i < proc - 1 ; i ++ )
292
+ {
293
+ if (ranges [i ].max > ranges [i + 1 ].min )
294
+ {
295
+ elog (WARNING , "Partitions %u and %u overlap. Disabling pathman for relation %u.." ,
296
+ ranges [i ].child_oid , ranges [i + 1 ].child_oid , parent_oid );
297
+ hash_search (relations , (const void * ) & parent_oid , HASH_REMOVE , & found );
298
+ }
299
+ }
288
300
}
289
301
}
290
302
@@ -303,7 +315,10 @@ cmp_range_entries(const void *p1, const void *p2)
303
315
return 0 ;
304
316
}
305
317
306
-
318
+ /*
319
+ * Validates range constraint. It MUST have the exact format:
320
+ * VARIABLE >= CONST AND VARIABLE < CONST
321
+ */
307
322
static bool
308
323
validate_range_constraint (Expr * expr , PartRelationInfo * prel , Datum * min , Datum * max )
309
324
{
@@ -349,12 +364,15 @@ validate_range_constraint(Expr *expr, PartRelationInfo *prel, Datum *min, Datum
349
364
return false;
350
365
* max = ((Const * ) right )-> constvalue ;
351
366
}
367
+ else
368
+ return false;
352
369
353
370
return true;
354
371
}
355
372
356
373
/*
357
- * Validate hash constraint. It should look like "Var % Const = Const"
374
+ * Validate hash constraint. It MUST have the exact format
375
+ * VARIABLE % CONST = CONST
358
376
*/
359
377
static bool
360
378
validate_hash_constraint (Expr * expr , PartRelationInfo * prel , int * hash )
@@ -366,14 +384,14 @@ validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
366
384
return false;
367
385
eqexpr = (OpExpr * ) expr ;
368
386
369
- /* is this an equality operator? */
387
+ /* Is this an equality operator? */
370
388
if (eqexpr -> opno != Int4EqualOperator )
371
389
return false;
372
390
373
391
if (!IsA (linitial (eqexpr -> args ), OpExpr ))
374
392
return false;
375
393
376
- /* is this a modulus operator? */
394
+ /* Is this a modulus operator? */
377
395
modexpr = (OpExpr * ) linitial (eqexpr -> args );
378
396
if (modexpr -> opno != 530 )
379
397
return false;
@@ -424,25 +442,19 @@ void
424
442
remove_relation_info (Oid relid )
425
443
{
426
444
PartRelationInfo * prel ;
427
- // HashRelationKey key;
428
445
RangeRelation * rangerel ;
429
446
430
447
prel = (PartRelationInfo * )
431
448
hash_search (relations , (const void * ) & relid , HASH_FIND , 0 );
432
449
433
- /* if there is nothing to remove then just return */
450
+ /* If there is nothing to remove then just return */
434
451
if (!prel )
435
452
return ;
436
453
437
- /* remove children relations */
454
+ /* Remove children relations */
438
455
switch (prel -> parttype )
439
456
{
440
457
case PT_HASH :
441
- // for (i=0; i<prel->children_count; i++)
442
- // {
443
- // key.parent_oid = relid;
444
- // key.hash = i;
445
- // }
446
458
free_dsm_array (& prel -> children );
447
459
break ;
448
460
case PT_RANGE :
0 commit comments