@@ -48,8 +48,8 @@ static void extract_op_func_and_ret_type(char *opname, Oid type1, Oid type2,
4848Oid * move_bound_op_ret_type );
4949
5050static Oid spawn_partitions_val (Oid parent_relid ,
51- Datum range_bound_min ,
52- Datum range_bound_max ,
51+ const Bound * range_bound_min ,
52+ const Bound * range_bound_max ,
5353Oid range_bound_type ,
5454Datum interval_binary ,
5555Oid interval_type ,
@@ -359,26 +359,27 @@ create_partitions_for_value_internal(Oid relid, Datum value, Oid value_type)
359359if (partid == InvalidOid )
360360{
361361RangeEntry * ranges = PrelGetRangesArray (prel );
362- Datum bound_min ,/* absolute MIN */
362+ Bound bound_min ,/* absolute MIN */
363363bound_max ;/* absolute MAX */
364364
365365Oid interval_type = InvalidOid ;
366366Datum interval_binary ,/* assigned 'width' of one partition */
367367interval_text ;
368368
369- /* Read max & min range values from PartRelationInfo */
370- bound_min = BoundGetValue (& ranges [0 ].min );
371- bound_max = BoundGetValue (& ranges [PrelLastChild (prel )].max );
369+ /* Copy datums in order to protect them from cache invalidation */
370+ bound_min = CopyBound (& ranges [0 ].min ,
371+ prel -> attbyval ,
372+ prel -> attlen );
372373
373- /* Copy datums on order to protect them from cache invalidation */
374- bound_min = datumCopy ( bound_min , prel -> attbyval ,prel -> attlen );
375- bound_max = datumCopy ( bound_max , prel -> attbyval , prel -> attlen );
374+ bound_max = CopyBound ( & ranges [ PrelLastChild ( prel )]. max ,
375+ prel -> attbyval ,
376+ prel -> attlen );
376377
377378/* Check if interval is set */
378379if (isnull [Anum_pathman_config_range_interval - 1 ])
379380{
380381elog (ERROR ,
381- "Could not find appropriate partition for key '%s'" ,
382+ "cannot find appropriate partition for key '%s'" ,
382383datum_to_cstring (value ,value_type ));
383384}
384385
@@ -392,7 +393,7 @@ create_partitions_for_value_internal(Oid relid, Datum value, Oid value_type)
392393
393394/* At last, spawn partitions to store the value */
394395partid = spawn_partitions_val (PrelParentRelid (prel ),
395- bound_min ,bound_max ,base_bound_type ,
396+ & bound_min ,& bound_max ,base_bound_type ,
396397interval_binary ,interval_type ,
397398value ,base_value_type );
398399}
@@ -455,14 +456,14 @@ extract_op_func_and_ret_type(char *opname, Oid type1, Oid type2,
455456 * it into account while searching for the 'cmp_proc'.
456457 */
457458static Oid
458- spawn_partitions_val (Oid parent_relid ,/* parent's Oid */
459- Datum range_bound_min ,/* parent's MIN boundary */
460- Datum range_bound_max ,/* parent's MAX boundary */
461- Oid range_bound_type ,/* type of boundary's value */
462- Datum interval_binary ,/* interval in binary form */
463- Oid interval_type ,/* INTERVALOID or prel->atttype */
464- Datum value ,/* value to be INSERTed */
465- Oid value_type )/* type of value */
459+ spawn_partitions_val (Oid parent_relid ,/* parent's Oid */
460+ const Bound * range_bound_min ,/* parent's MIN boundary */
461+ const Bound * range_bound_max ,/* parent's MAX boundary */
462+ Oid range_bound_type ,/* type of boundary's value */
463+ Datum interval_binary ,/* interval in binary form */
464+ Oid interval_type ,/* INTERVALOID or prel->atttype */
465+ Datum value ,/* value to be INSERTed */
466+ Oid value_type )/* type of value */
466467{
467468bool should_append ;/* append or prepend? */
468469
@@ -475,27 +476,37 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
475476Datum cur_leading_bound ,/* boundaries of a new partition */
476477cur_following_bound ;
477478
479+ Bound value_bound = MakeBound (value );
480+
478481Oid last_partition = InvalidOid ;
479482
480483
481484fill_type_cmp_fmgr_info (& cmp_value_bound_finfo ,value_type ,range_bound_type );
482485
486+ /* Is it possible to append\prepend a partition? */
487+ if (IsInfinite (range_bound_min )&& IsInfinite (range_bound_max ))
488+ ereport (ERROR , (errmsg ("cannot spawn a partition" ),
489+ errdetail ("both bounds are infinite" )));
490+
483491/* value >= MAX_BOUNDARY */
484- if (check_ge (& cmp_value_bound_finfo ,value ,range_bound_max ))
492+ else if (cmp_bounds (& cmp_value_bound_finfo ,
493+ & value_bound ,range_bound_max ) >=0 )
485494{
486495should_append = true;
487- cur_leading_bound = range_bound_max ;
496+ cur_leading_bound = BoundGetValue ( range_bound_max ) ;
488497}
489498
490499/* value < MIN_BOUNDARY */
491- else if (check_lt (& cmp_value_bound_finfo ,value ,range_bound_min ))
500+ else if (cmp_bounds (& cmp_value_bound_finfo ,
501+ & value_bound ,range_bound_min )< 0 )
492502{
493503should_append = false;
494- cur_leading_bound = range_bound_min ;
504+ cur_leading_bound = BoundGetValue ( range_bound_min ) ;
495505}
496506
497507/* There's a gap, halt and emit ERROR */
498- else elog (ERROR ,"cannot spawn a partition inside a gap" );
508+ else ereport (ERROR , (errmsg ("cannot spawn a partition" ),
509+ errdetail ("there is a gap" )));
499510
500511/* Fetch operator's underlying function and ret type */
501512extract_op_func_and_ret_type (should_append ?"+" :"-" ,
@@ -541,7 +552,6 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
541552check_ge (& cmp_value_bound_finfo ,value ,cur_leading_bound ) :
542553check_lt (& cmp_value_bound_finfo ,value ,cur_leading_bound ))
543554{
544- Datum args [2 ];
545555Bound bounds [2 ];
546556
547557/* Assign the 'following' boundary to current 'leading' value */
@@ -552,11 +562,8 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
552562cur_leading_bound ,
553563interval_binary );
554564
555- args [0 ]= should_append ?cur_following_bound :cur_leading_bound ;
556- args [1 ]= should_append ?cur_leading_bound :cur_following_bound ;
557-
558- MakeBound (& bounds [0 ],args [0 ],FINITE );
559- MakeBound (& bounds [1 ],args [1 ],FINITE );
565+ bounds [0 ]= MakeBound (should_append ?cur_following_bound :cur_leading_bound );
566+ bounds [1 ]= MakeBound (should_append ?cur_leading_bound :cur_following_bound );
560567
561568last_partition = create_single_range_partition_internal (parent_relid ,
562569& bounds [0 ],& bounds [1 ],
@@ -1143,7 +1150,7 @@ build_raw_range_check_tree(char *attname,
11431150}
11441151
11451152if (and_oper -> args == NIL )
1146- elog (ERROR ,"Cannot create infinite range constraint" );
1153+ elog (ERROR ,"cannot create infinite range constraint" );
11471154
11481155return (Node * )and_oper ;
11491156}
@@ -1207,39 +1214,23 @@ check_range_available(Oid parent_relid,
12071214{
12081215int c1 ,c2 ;
12091216
1210- /*
1211- * If the range we're checking starts with minus infinity or current
1212- * range ends in plus infinity then the left boundary of the first
1213- * range is on the left. Otherwise compare specific values
1214- */
1215- // c1 = (IsInfinite(start) || IsInfinite(&ranges[i].max)) ?
1216- // -1 :
1217- // FunctionCall2(&cmp_func,
1218- // BoundGetValue(start),
1219- // BoundGetValue(&ranges[i].max));
1220- /*
1221- * Similary check that right boundary of the range we're checking is on
1222- * the right of the beginning of the current one
1223- */
1224- // c2 = (IsInfinite(end) || IsInfinite(&ranges[i].min)) ?
1225- // 1 :
1226- // FunctionCall2(&cmp_func,
1227- // BoundGetValue(end),
1228- // BoundGetValue(&ranges[i].min));
1229-
12301217c1 = cmp_bounds (& cmp_func ,start ,& ranges [i ].max );
12311218c2 = cmp_bounds (& cmp_func ,end ,& ranges [i ].min );
12321219
1233- /* There'ssomeone ! */
1220+ /* There'ssomething ! */
12341221if (c1 < 0 && c2 > 0 )
12351222{
12361223if (raise_error )
12371224elog (ERROR ,"specified range [%s, %s) overlaps "
12381225"with existing partitions" ,
1239- !IsInfinite (start ) ?datum_to_cstring (BoundGetValue (start ),value_type ) :"NULL" ,
1240- !IsInfinite (end ) ?datum_to_cstring (BoundGetValue (end ),value_type ) :"NULL" );
1241- else
1242- return false;
1226+ !IsInfinite (start ) ?
1227+ datum_to_cstring (BoundGetValue (start ),value_type ) :
1228+ "NULL" ,
1229+ !IsInfinite (end ) ?
1230+ datum_to_cstring (BoundGetValue (end ),value_type ) :
1231+ "NULL" );
1232+
1233+ else return false;
12431234}
12441235}
12451236