range_adjacent_reimplementation-2.patch

text/x-patch

Filename: range_adjacent_reimplementation-2.patch
Type: text/x-patch
Part: 0
Message: Re: range_adjacent and discrete ranges

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
new/rangetypes.c 49 11
*** /home/postgres/pgsql/src/backend/utils/adt/rangetypes.c	Tue Nov 22 23:18:51 2011
--- new/rangetypes.c	Wed Nov 23 16:29:20 2011
***************
*** 699,704 ****
--- 699,706 ----
  				upper2;
  	bool		empty1,
  				empty2;
+ 	RangeType  *r3;
+ 	int			cmp;
  
  	/* Different types should be prevented by ANYRANGE matching rules */
  	if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
***************
*** 714,736 ****
  		PG_RETURN_BOOL(false);
  
  	/*
! 	 * For two ranges to be adjacent, the lower boundary of one range has to
! 	 * match the upper boundary of the other. However, the inclusivity of
! 	 * those two boundaries must also be different.
  	 *
! 	 * The semantics for range_cmp_bounds aren't quite what we need here, so
! 	 * we do the comparison more directly.
  	 */
! 	if (lower1.inclusive != upper2.inclusive)
  	{
! 		if (range_cmp_bound_values(typcache, &lower1, &upper2) == 0)
! 			PG_RETURN_BOOL(true);
  	}
  
! 	if (upper1.inclusive != lower2.inclusive)
  	{
! 		if (range_cmp_bound_values(typcache, &upper1, &lower2) == 0)
! 			PG_RETURN_BOOL(true);
  	}
  
  	PG_RETURN_BOOL(false);
--- 716,774 ----
  		PG_RETURN_BOOL(false);
  
  	/*
! 	 * Given two ranges A..B and C..D, where B < C, the ranges are adjacent
! 	 * if and only if the range B..C is empty, where inclusivity of these two
! 	 * bounds is inverted compared to the original bounds.  For discrete
! 	 * ranges, we have to rely on the canonicalization function to normalize
! 	 * B..C to empty if it contains no elements of the subtype.  (If there is
! 	 * no canonicalization function, it's impossible for such a range to
! 	 * normalize to empty, so we needn't bother to try.)
! 	 *
! 	 * If B == C, the ranges are adjacent only if these bounds have different
! 	 * inclusive flags (i.e., exactly one of the ranges includes the common
! 	 * boundary point).
  	 *
! 	 * And if B > C then the ranges cannot be adjacent in this order, but we
! 	 * must consider the other order (i.e., check D <= A).
  	 */
! 	cmp = range_cmp_bound_values(typcache, &upper1, &lower2);
! 	if (cmp < 0)
! 	{
! 		/* in a continuous subtype, there are assumed to be points between */
! 		if (!OidIsValid(typcache->rng_canonical_finfo.fn_oid))
! 			PG_RETURN_BOOL(false);
! 		/* flip the inclusion flags */
! 		upper1.inclusive = !upper1.inclusive;
! 		lower2.inclusive = !lower2.inclusive;
! 		/* change upper/lower labels to avoid Assert failures */
! 		upper1.lower = true;
! 		lower2.lower = false;
! 		r3 = make_range(typcache, &upper1, &lower2, false);
! 		PG_RETURN_BOOL(RangeIsEmpty(r3));
! 	}
! 	if (cmp == 0)
  	{
! 		PG_RETURN_BOOL(upper1.inclusive != lower2.inclusive);
  	}
  
! 	cmp = range_cmp_bound_values(typcache, &upper2, &lower1);
! 	if (cmp < 0)
! 	{
! 		/* in a continuous subtype, there are assumed to be points between */
! 		if (!OidIsValid(typcache->rng_canonical_finfo.fn_oid))
! 			PG_RETURN_BOOL(false);
! 		/* flip the inclusion flags */
! 		upper2.inclusive = !upper2.inclusive;
! 		lower1.inclusive = !lower1.inclusive;
! 		/* change upper/lower labels to avoid Assert failures */
! 		upper2.lower = true;
! 		lower1.lower = false;
! 		r3 = make_range(typcache, &upper2, &lower1, false);
! 		PG_RETURN_BOOL(RangeIsEmpty(r3));
! 	}
! 	if (cmp == 0)
  	{
! 		PG_RETURN_BOOL(upper2.inclusive != lower1.inclusive);
  	}
  
  	PG_RETURN_BOOL(false);