Skip to content

Commit 74d8413

Browse files
committed
extra constraint checks
1 parent ee78b34 commit 74d8413

File tree

3 files changed

+114
-98
lines changed

3 files changed

+114
-98
lines changed

init.c

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ get_extension_schema()
6464
return NULL;
6565
}
6666

67+
/*
68+
* Loads partitioned tables structure to hashtable
69+
*/
6770
void
6871
load_relations_hashtable(bool reinitialize)
6972
{
@@ -85,14 +88,14 @@ load_relations_hashtable(bool reinitialize)
8588
SPI_connect();
8689
schema = get_extension_schema();
8790

88-
/* if extension doesn't exist then just quit */
91+
/* If extension isn't exist then just quit */
8992
if (!schema)
9093
{
9194
SPI_finish();
9295
return;
9396
}
9497

95-
/* put schema name to the query */
98+
/* Put schema name to the query */
9699
query = psprintf(sql, schema);
97100
ret = SPI_exec(query, 0);
98101
proc = SPI_processed;
@@ -115,27 +118,21 @@ load_relations_hashtable(bool reinitialize)
115118
prel->atttype = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 4, &isnull));
116119

117120
part_oids = lappend_int(part_oids, oid);
118-
119-
/* children will be filled in later */
120-
// prinfo->children = NIL;
121121
}
122122
}
123123
pfree(query);
124124

125-
/* load children information */
125+
/* Load children information */
126126
foreach(lc, part_oids)
127127
{
128128
Oid oid = (int) lfirst_int(lc);
129129

130130
prel = (PartRelationInfo*)
131131
hash_search(relations, (const void *)&oid, HASH_FIND, NULL);
132132

133-
// load_check_constraints(oid);
134-
135133
switch(prel->parttype)
136134
{
137135
case PT_RANGE:
138-
// load_range_restrictions(oid);
139136
if (reinitialize && prel->children.length > 0)
140137
{
141138
RangeRelation *rangerel = (RangeRelation *)
@@ -168,7 +165,7 @@ create_relations_hashtable()
168165
ctl.keysize = sizeof(int);
169166
ctl.entrysize = sizeof(PartRelationInfo);
170167

171-
/* already exists, recreate */
168+
/* Already exists, recreate */
172169
if (relations != NULL)
173170
hash_destroy(relations);
174171

@@ -196,7 +193,7 @@ load_check_constraints(Oid parent_oid)
196193
prel = (PartRelationInfo*)
197194
hash_search(relations, (const void *) &parent_oid, HASH_FIND, &found);
198195

199-
/* skip if already loaded */
196+
/* Skip if already loaded */
200197
if (prel->children.length > 0)
201198
return;
202199

@@ -237,8 +234,6 @@ load_check_constraints(Oid parent_oid)
237234
char *conbin;
238235
Expr *expr;
239236

240-
// HeapTuple reltuple;
241-
// Form_pg_class pg_class_tuple;
242237
Form_pg_constraint con;
243238

244239
con = (Form_pg_constraint) GETSTRUCT(tuple);
@@ -255,8 +250,12 @@ load_check_constraints(Oid parent_oid)
255250
{
256251
case PT_RANGE:
257252
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);
259257
continue;
258+
}
260259

261260
re.child_oid = con->conrelid;
262261
re.min = min;
@@ -267,24 +266,37 @@ load_check_constraints(Oid parent_oid)
267266

268267
case PT_HASH:
269268
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);
271273
continue;
274+
}
272275
children[hash] = con->conrelid;
273276
}
274277
}
275278
prel->children_count = proc;
276279

277280
if (prel->parttype == PT_RANGE)
278281
{
279-
/* sort ascending */
282+
/* Sort ascending */
280283
qsort(ranges, proc, sizeof(RangeEntry), cmp_range_entries);
281284

282-
/* copy oids to prel */
285+
/* Copy oids to prel */
283286
for(i=0; i < proc; i++)
284287
children[i] = ranges[i].child_oid;
285288
}
286289

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+
}
288300
}
289301
}
290302

@@ -303,7 +315,10 @@ cmp_range_entries(const void *p1, const void *p2)
303315
return 0;
304316
}
305317

306-
318+
/*
319+
* Validates range constraint. It MUST have the exact format:
320+
* VARIABLE >= CONST AND VARIABLE < CONST
321+
*/
307322
static bool
308323
validate_range_constraint(Expr *expr, PartRelationInfo *prel, Datum *min, Datum *max)
309324
{
@@ -349,12 +364,15 @@ validate_range_constraint(Expr *expr, PartRelationInfo *prel, Datum *min, Datum
349364
return false;
350365
*max = ((Const*) right)->constvalue;
351366
}
367+
else
368+
return false;
352369

353370
return true;
354371
}
355372

356373
/*
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
358376
*/
359377
static bool
360378
validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
@@ -366,14 +384,14 @@ validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
366384
return false;
367385
eqexpr = (OpExpr *) expr;
368386

369-
/* is this an equality operator? */
387+
/* Is this an equality operator? */
370388
if (eqexpr->opno != Int4EqualOperator)
371389
return false;
372390

373391
if (!IsA(linitial(eqexpr->args), OpExpr))
374392
return false;
375393

376-
/* is this a modulus operator? */
394+
/* Is this a modulus operator? */
377395
modexpr = (OpExpr *) linitial(eqexpr->args);
378396
if (modexpr->opno != 530)
379397
return false;
@@ -424,25 +442,19 @@ void
424442
remove_relation_info(Oid relid)
425443
{
426444
PartRelationInfo *prel;
427-
// HashRelationKey key;
428445
RangeRelation *rangerel;
429446

430447
prel = (PartRelationInfo *)
431448
hash_search(relations, (const void *) &relid, HASH_FIND, 0);
432449

433-
/* if there is nothing to remove then just return */
450+
/* If there is nothing to remove then just return */
434451
if (!prel)
435452
return;
436453

437-
/* remove children relations */
454+
/* Remove children relations */
438455
switch (prel->parttype)
439456
{
440457
case PT_HASH:
441-
// for (i=0; i<prel->children_count; i++)
442-
// {
443-
// key.parent_oid = relid;
444-
// key.hash = i;
445-
// }
446458
free_dsm_array(&prel->children);
447459
break;
448460
case PT_RANGE:

0 commit comments

Comments
 (0)