From 54c80a3434b5ad3b3841b402097d7e3821f36c85 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 27 Jun 2005 00:48:07 +0000
Subject: [PATCH] Adjust contrib/seg &< and &> operators so that r-tree
 indexing logic works properly for 1-D comparisons.  Fix some other errors
 such as bogus commutator specifications.

---
 contrib/seg/README.seg         | 20 +++++++------
 contrib/seg/expected/seg.out   | 12 ++++----
 contrib/seg/expected/seg_1.out | 12 ++++----
 contrib/seg/seg.c              | 18 +++++++-----
 contrib/seg/seg.sql.in         | 52 ++++++++++++++++------------------
 5 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/contrib/seg/README.seg b/contrib/seg/README.seg
index e738f180e8a..9e741756c33 100644
--- a/contrib/seg/README.seg
+++ b/contrib/seg/README.seg
@@ -214,7 +214,7 @@ have just 2 significant digits.
 USAGE
 =====
 
-The access method for SEG is a GiST (gist_seg_ops), which is a
+The access method for SEG is a GiST index (gist_seg_ops), which is a
 generalization of R-tree. GiSTs allow the postgres implementation of
 R-tree, originally encoded to support 2-D geometric types such as
 boxes and polygons, to be used with any data type whose data domain
@@ -236,23 +236,27 @@ The operators supported by the GiST access method include:
 [a, b] >> [c, d]	Is right of
 
 	[a, b] is occurs entirely to the right of [c, d]. 
-	[a, b] >> [c, d] is true if b > c and false otherwise
+	[a, b] >> [c, d] is true if a > d and false otherwise
 
-[a, b] &< [c, d]	Over left
+[a, b] &< [c, d]	Overlaps or is left of
 
-	The segment [a, b] overlaps the segment [c, d] in such a way
-	that a <= c <= b and b <= d
+	This might be better read as "does not extend to right of".
+	It is true when b <= d.
 
-[a, b] &> [c, d]	Over right
+[a, b] &> [c, d]	Overlaps or is right of
 
-	The segment [a, b] overlaps the segment [c, d] in such a way
-	that a > c and b <= c <= d
+	This might be better read as "does not extend to left of".
+	It is true when a >= c.
 
 [a, b] = [c, d]		Same as
 
 	The segments [a, b] and [c, d] are identical, that is, a == b
 	and c == d
 
+[a, b] && [c, d]	Overlaps
+
+	The segments [a, b] and [c, d] overlap.
+
 [a, b] @ [c, d]		Contains
 
 	The segment [a, b] contains the segment [c, d], that is, 
diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out
index 49f4f7dee5d..06971ae265b 100644
--- a/contrib/seg/expected/seg.out
+++ b/contrib/seg/expected/seg.out
@@ -557,7 +557,7 @@ SELECT '1'::seg &< '1'::seg AS bool;
 SELECT '1'::seg &< '2'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 1'::seg &< '0'::seg AS bool;
@@ -575,7 +575,7 @@ SELECT '0 .. 1'::seg &< '1'::seg AS bool;
 SELECT '0 .. 1'::seg &< '2'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool;
@@ -605,7 +605,7 @@ SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool;
 SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 -- overlap on the right
@@ -625,7 +625,7 @@ SELECT '1'::seg &> '1'::seg AS bool;
 SELECT '2'::seg &> '1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0'::seg &> '0 .. 1'::seg AS bool;
@@ -643,7 +643,7 @@ SELECT '1'::seg &> '0 .. 1'::seg AS bool;
 SELECT '2'::seg &> '0 .. 1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool;
@@ -673,7 +673,7 @@ SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool;
 SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 -- left
diff --git a/contrib/seg/expected/seg_1.out b/contrib/seg/expected/seg_1.out
index 732525c12eb..2c446b7cc6e 100644
--- a/contrib/seg/expected/seg_1.out
+++ b/contrib/seg/expected/seg_1.out
@@ -557,7 +557,7 @@ SELECT '1'::seg &< '1'::seg AS bool;
 SELECT '1'::seg &< '2'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 1'::seg &< '0'::seg AS bool;
@@ -575,7 +575,7 @@ SELECT '0 .. 1'::seg &< '1'::seg AS bool;
 SELECT '0 .. 1'::seg &< '2'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool;
@@ -605,7 +605,7 @@ SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool;
 SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 -- overlap on the right
@@ -625,7 +625,7 @@ SELECT '1'::seg &> '1'::seg AS bool;
 SELECT '2'::seg &> '1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0'::seg &> '0 .. 1'::seg AS bool;
@@ -643,7 +643,7 @@ SELECT '1'::seg &> '0 .. 1'::seg AS bool;
 SELECT '2'::seg &> '0 .. 1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool;
@@ -673,7 +673,7 @@ SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool;
 SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool;
  bool 
 ------
- f
+ t
 (1 row)
 
 -- left
diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c
index 4bd9b9a59fd..5bdad542e4a 100644
--- a/contrib/seg/seg.c
+++ b/contrib/seg/seg.c
@@ -204,7 +204,7 @@ gseg_consistent(GISTENTRY *entry,
 				StrategyNumber strategy)
 {
 	/*
-	 * * if entry is not leaf, use gseg_internal_consistent, * else use
+	 * if entry is not leaf, use gseg_internal_consistent, else use
 	 * gseg_leaf_consistent
 	 */
 	if (GIST_LEAF(entry))
@@ -517,15 +517,19 @@ gseg_internal_consistent(SEG * key,
 	switch (strategy)
 	{
 		case RTLeftStrategyNumber:
+			retval = (bool) !seg_over_right(key, query);
+			break;
 		case RTOverLeftStrategyNumber:
-			retval = (bool) seg_over_left(key, query);
+			retval = (bool) !seg_right(key, query);
 			break;
 		case RTOverlapStrategyNumber:
 			retval = (bool) seg_overlap(key, query);
 			break;
 		case RTOverRightStrategyNumber:
+			retval = (bool) !seg_left(key, query);
+			break;
 		case RTRightStrategyNumber:
-			retval = (bool) seg_right(key, query);
+			retval = (bool) !seg_over_left(key, query);
 			break;
 		case RTSameStrategyNumber:
 		case RTContainsStrategyNumber:
@@ -586,12 +590,12 @@ seg_overlap(SEG * a, SEG * b)
 		);
 }
 
-/*	seg_overleft -- is the right edge of (a) located to the left of the right edge of (b)?
+/*	seg_overleft -- is the right edge of (a) located at or left of the right edge of (b)?
  */
 bool
 seg_over_left(SEG * a, SEG * b)
 {
-	return (a->upper <= b->upper && !seg_left(a, b) && !seg_right(a, b));
+	return (a->upper <= b->upper);
 }
 
 /*	seg_left -- is (a) entirely on the left of (b)?
@@ -610,12 +614,12 @@ seg_right(SEG * a, SEG * b)
 	return (a->lower > b->upper);
 }
 
-/*	seg_overright -- is the left edge of (a) located to the right of the left edge of (b)?
+/*	seg_overright -- is the left edge of (a) located at or right of the left edge of (b)?
  */
 bool
 seg_over_right(SEG * a, SEG * b)
 {
-	return (a->lower >= b->lower && !seg_left(a, b) && !seg_right(a, b));
+	return (a->lower >= b->lower);
 }
 
 
diff --git a/contrib/seg/seg.sql.in b/contrib/seg/seg.sql.in
index 52d2f61ad7a..ca30a30ba57 100644
--- a/contrib/seg/seg.sql.in
+++ b/contrib/seg/seg.sql.in
@@ -32,23 +32,23 @@ COMMENT ON TYPE seg IS
 CREATE FUNCTION seg_over_left(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_over_left(seg, seg) IS
-'is over and left of';
+'overlaps or is left of';
 
 CREATE FUNCTION seg_over_right(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_over_right(seg, seg) IS
-'is over and right of';
+'overlaps or is right of';
 
 CREATE FUNCTION seg_left(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_left(seg, seg) IS
 'is left of';
@@ -56,18 +56,18 @@ COMMENT ON FUNCTION seg_left(seg, seg) IS
 CREATE FUNCTION seg_right(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_right(seg, seg) IS
 'is right of';
 
 
--- Comparison methods
+-- Scalar comparison methods
 
 CREATE FUNCTION seg_lt(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_lt(seg, seg) IS
 'less than';
@@ -75,7 +75,7 @@ COMMENT ON FUNCTION seg_lt(seg, seg) IS
 CREATE FUNCTION seg_le(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_le(seg, seg) IS
 'less than or equal';
@@ -83,7 +83,7 @@ COMMENT ON FUNCTION seg_le(seg, seg) IS
 CREATE FUNCTION seg_gt(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_gt(seg, seg) IS
 'greater than';
@@ -91,7 +91,7 @@ COMMENT ON FUNCTION seg_gt(seg, seg) IS
 CREATE FUNCTION seg_ge(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_ge(seg, seg) IS
 'greater than or equal';
@@ -99,7 +99,7 @@ COMMENT ON FUNCTION seg_ge(seg, seg) IS
 CREATE FUNCTION seg_contains(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_contains(seg, seg) IS
 'contains';
@@ -107,7 +107,7 @@ COMMENT ON FUNCTION seg_contains(seg, seg) IS
 CREATE FUNCTION seg_contained(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_contained(seg, seg) IS
 'contained in';
@@ -115,7 +115,7 @@ COMMENT ON FUNCTION seg_contained(seg, seg) IS
 CREATE FUNCTION seg_overlap(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_overlap(seg, seg) IS
 'overlaps';
@@ -123,7 +123,7 @@ COMMENT ON FUNCTION seg_overlap(seg, seg) IS
 CREATE FUNCTION seg_same(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_same(seg, seg) IS
 'same as';
@@ -131,7 +131,7 @@ COMMENT ON FUNCTION seg_same(seg, seg) IS
 CREATE FUNCTION seg_different(seg, seg)
 RETURNS bool
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_different(seg, seg) IS
 'different';
@@ -141,36 +141,36 @@ COMMENT ON FUNCTION seg_different(seg, seg) IS
 CREATE OR REPLACE FUNCTION seg_cmp(seg, seg)
 RETURNS int4
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' STRICT;
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 COMMENT ON FUNCTION seg_cmp(seg, seg) IS 'btree comparison function';
 
 CREATE FUNCTION seg_union(seg, seg)
 RETURNS seg
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 CREATE FUNCTION seg_inter(seg, seg)
 RETURNS seg
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 CREATE FUNCTION seg_size(seg)
 RETURNS float4
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 -- miscellaneous
 
 CREATE FUNCTION seg_upper(seg)
 RETURNS float4
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 CREATE FUNCTION seg_lower(seg)
 RETURNS float4
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT IMMUTABLE;
 
 
 --
@@ -230,7 +230,6 @@ CREATE OPERATOR &< (
 	LEFTARG = seg,
 	RIGHTARG = seg,
 	PROCEDURE = seg_over_left,
-	COMMUTATOR = '&>',
 	RESTRICT = positionsel,
 	JOIN = positionjoinsel
 );
@@ -240,15 +239,14 @@ CREATE OPERATOR && (
 	RIGHTARG = seg,
 	PROCEDURE = seg_overlap,
 	COMMUTATOR = '&&',
-	RESTRICT = positionsel,
-	JOIN = positionjoinsel
+	RESTRICT = areasel,
+	JOIN = areajoinsel
 );
 
 CREATE OPERATOR &> (
 	LEFTARG = seg,
 	RIGHTARG = seg,
 	PROCEDURE = seg_over_right,
-	COMMUTATOR = '&<',
 	RESTRICT = positionsel,
 	JOIN = positionjoinsel
 );
@@ -321,7 +319,7 @@ LANGUAGE 'C';
 CREATE FUNCTION gseg_penalty(internal,internal,internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict);
+LANGUAGE 'C' STRICT;
 
 CREATE FUNCTION gseg_picksplit(internal, internal)
 RETURNS internal
-- 
GitLab