@@ -64,6 +64,9 @@ get_extension_schema()
6464return NULL ;
6565}
6666
67+ /*
68+ * Loads partitioned tables structure to hashtable
69+ */
6770void
6871load_relations_hashtable (bool reinitialize )
6972{
@@ -85,14 +88,14 @@ load_relations_hashtable(bool reinitialize)
8588SPI_connect ();
8689schema = get_extension_schema ();
8790
88- /*if extensiondoesn 't exist then just quit */
91+ /*If extensionisn 't exist then just quit */
8992if (!schema )
9093{
9194SPI_finish ();
9295return ;
9396}
9497
95- /*put schema name to the query */
98+ /*Put schema name to the query */
9699query = psprintf (sql ,schema );
97100ret = SPI_exec (query ,0 );
98101proc = SPI_processed ;
@@ -115,27 +118,21 @@ load_relations_hashtable(bool reinitialize)
115118prel -> atttype = DatumGetObjectId (SPI_getbinval (tuple ,tupdesc ,4 ,& isnull ));
116119
117120part_oids = lappend_int (part_oids ,oid );
118-
119- /* children will be filled in later */
120- // prinfo->children = NIL;
121121}
122122}
123123pfree (query );
124124
125- /*load children information */
125+ /*Load children information */
126126foreach (lc ,part_oids )
127127{
128128Oid oid = (int )lfirst_int (lc );
129129
130130prel = (PartRelationInfo * )
131131hash_search (relations , (const void * )& oid ,HASH_FIND ,NULL );
132132
133- // load_check_constraints(oid);
134-
135133switch (prel -> parttype )
136134{
137135case PT_RANGE :
138- // load_range_restrictions(oid);
139136if (reinitialize && prel -> children .length > 0 )
140137{
141138RangeRelation * rangerel = (RangeRelation * )
@@ -168,7 +165,7 @@ create_relations_hashtable()
168165ctl .keysize = sizeof (int );
169166ctl .entrysize = sizeof (PartRelationInfo );
170167
171- /*already exists, recreate */
168+ /*Already exists, recreate */
172169if (relations != NULL )
173170hash_destroy (relations );
174171
@@ -196,7 +193,7 @@ load_check_constraints(Oid parent_oid)
196193prel = (PartRelationInfo * )
197194hash_search (relations , (const void * )& parent_oid ,HASH_FIND ,& found );
198195
199- /*skip if already loaded */
196+ /*Skip if already loaded */
200197if (prel -> children .length > 0 )
201198return ;
202199
@@ -237,8 +234,6 @@ load_check_constraints(Oid parent_oid)
237234char * conbin ;
238235Expr * expr ;
239236
240- // HeapTuplereltuple;
241- // Form_pg_class pg_class_tuple;
242237Form_pg_constraint con ;
243238
244239con = (Form_pg_constraint )GETSTRUCT (tuple );
@@ -255,8 +250,12 @@ load_check_constraints(Oid parent_oid)
255250{
256251case PT_RANGE :
257252if (!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 );
259257continue ;
258+ }
260259
261260re .child_oid = con -> conrelid ;
262261re .min = min ;
@@ -267,24 +266,37 @@ load_check_constraints(Oid parent_oid)
267266
268267case PT_HASH :
269268if (!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 );
271273continue ;
274+ }
272275children [hash ]= con -> conrelid ;
273276}
274277}
275278prel -> children_count = proc ;
276279
277280if (prel -> parttype == PT_RANGE )
278281{
279- /*sort ascending */
282+ /*Sort ascending */
280283qsort (ranges ,proc ,sizeof (RangeEntry ),cmp_range_entries );
281284
282- /*copy oids to prel */
285+ /*Copy oids to prel */
283286for (i = 0 ;i < proc ;i ++ )
284287children [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)
303315return 0 ;
304316}
305317
306-
318+ /*
319+ * Validates range constraint. It MUST have the exact format:
320+ * VARIABLE >= CONST AND VARIABLE < CONST
321+ */
307322static bool
308323validate_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
349364return false;
350365* max = ((Const * )right )-> constvalue ;
351366}
367+ else
368+ return false;
352369
353370return 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 */
359377static bool
360378validate_hash_constraint (Expr * expr ,PartRelationInfo * prel ,int * hash )
@@ -366,14 +384,14 @@ validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
366384return false;
367385eqexpr = (OpExpr * )expr ;
368386
369- /*is this an equality operator? */
387+ /*Is this an equality operator? */
370388if (eqexpr -> opno != Int4EqualOperator )
371389return false;
372390
373391if (!IsA (linitial (eqexpr -> args ),OpExpr ))
374392return false;
375393
376- /*is this a modulus operator? */
394+ /*Is this a modulus operator? */
377395modexpr = (OpExpr * )linitial (eqexpr -> args );
378396if (modexpr -> opno != 530 )
379397return false;
@@ -424,25 +442,19 @@ void
424442remove_relation_info (Oid relid )
425443{
426444PartRelationInfo * prel ;
427- // HashRelationKeykey;
428445RangeRelation * rangerel ;
429446
430447prel = (PartRelationInfo * )
431448hash_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 */
434451if (!prel )
435452return ;
436453
437- /*remove children relations */
454+ /*Remove children relations */
438455switch (prel -> parttype )
439456{
440457case PT_HASH :
441- // for (i=0; i<prel->children_count; i++)
442- // {
443- // key.parent_oid = relid;
444- // key.hash = i;
445- // }
446458free_dsm_array (& prel -> children );
447459break ;
448460case PT_RANGE :