Thread: Bogus documentation for bogus geometric operators

Bogus documentation for bogus geometric operators

From
Tom Lane
Date:
While revising the docs for the geometric operators, I came across
these entries:

<^    Is below (allows touching)?    circle '((0,0),1)' <^ circle '((0,5),1)'
>^    Is above (allows touching)?    circle '((0,5),1)' >^ circle '((0,0),1)'

These have got more than a few problems:

1. There are no such operators for circles, so the examples are pure
fantasy.

2. What these operators do exist for is points (point_below, point_above
respectively) and boxes (box_below_eq, box_above_eq).  However, the
stated behavior is not what the point functions actually do:

point_below(PG_FUNCTION_ARGS)
...
    PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));

point_above(PG_FUNCTION_ARGS)
...
    PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));

So point_below would be more accurately described as "is strictly below",
so its operator name really ought to be <<|.  And point_above is "is
strictly above", so its operator name ought to be |>>.

3. The box functions do seem to be correctly documented:

box_below_eq(PG_FUNCTION_ARGS)
...
    PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));

box_above_eq(PG_FUNCTION_ARGS)
...
    PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));

But there are comments in the source code to the effect of

 * box_below_eq and box_above_eq are obsolete versions that (probably
 * erroneously) accept the equal-boundaries case.  Since these are not
 * in sync with the box_left and box_right code, they are deprecated and
 * not supported in the PG 8.1 rtree operator class extension.

I'm not sure how seriously to take this deprecation comment, but it
is true that box_below (<<|) and box_above (|>>) have analogs for
other data types while these functions don't.

4. Just for extra fun, these point operators are listed in some
GIST and SP-GIST opclasses; though the box ones are not, as per
that code comment.

Perhaps it's too late in the v13 cycle to actually do anything
about this code-wise, but what should I do documentation-wise?
I'm certainly not eager to document that these operators behave
inconsistently depending on which type you're talking about.

            regards, tom lane



Re: Bogus documentation for bogus geometric operators

From
Emre Hasegeli
Date:
> Perhaps it's too late in the v13 cycle to actually do anything
> about this code-wise, but what should I do documentation-wise?
> I'm certainly not eager to document that these operators behave
> inconsistently depending on which type you're talking about.

I don't think we need to worry too much about doing something in the
v13 cycle.  The geometric operators had and evidently still have so
many bugs.  Nobody complains about them other than the developers who
read the code.

I am happy to prepare a patch for the next release to fix the current
operators and add the missing ones.



Re: Bogus documentation for bogus geometric operators

From
Tom Lane
Date:
Emre Hasegeli <emre@hasegeli.com> writes:
>> Perhaps it's too late in the v13 cycle to actually do anything
>> about this code-wise, but what should I do documentation-wise?
>> I'm certainly not eager to document that these operators behave
>> inconsistently depending on which type you're talking about.

> I don't think we need to worry too much about doing something in the
> v13 cycle.  The geometric operators had and evidently still have so
> many bugs.  Nobody complains about them other than the developers who
> read the code.

Yeah, I ended up just documenting the current state of affairs.

> I am happy to prepare a patch for the next release to fix the current
> operators and add the missing ones.

Sounds great!

            regards, tom lane



Re: Bogus documentation for bogus geometric operators

From
Emre Hasegeli
Date:
> While revising the docs for the geometric operators, I came across
> these entries:
>
> <^      Is below (allows touching)?     circle '((0,0),1)' <^ circle '((0,5),1)'
> >^      Is above (allows touching)?     circle '((0,5),1)' >^ circle '((0,0),1)'
>
> These have got more than a few problems:
>
> 1. There are no such operators for circles, so the examples are pure
> fantasy.
>
> 2. What these operators do exist for is points (point_below, point_above
> respectively) and boxes (box_below_eq, box_above_eq).  However, the
> stated behavior is not what the point functions actually do:
>
> point_below(PG_FUNCTION_ARGS)
> ...
>         PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
>
> point_above(PG_FUNCTION_ARGS)
> ...
>         PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
>
> So point_below would be more accurately described as "is strictly below",
> so its operator name really ought to be <<|.  And point_above is "is
> strictly above", so its operator name ought to be |>>.

I prepared a patch to add <<| and |>> operators for points to
deprecate the previous ones.

> 3. The box functions do seem to be correctly documented:
>
> box_below_eq(PG_FUNCTION_ARGS)
> ...
>         PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
>
> box_above_eq(PG_FUNCTION_ARGS)
> ...
>         PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
>
> But there are comments in the source code to the effect of
>
>  * box_below_eq and box_above_eq are obsolete versions that (probably
>  * erroneously) accept the equal-boundaries case.  Since these are not
>  * in sync with the box_left and box_right code, they are deprecated and
>  * not supported in the PG 8.1 rtree operator class extension.
>
> I'm not sure how seriously to take this deprecation comment, but it
> is true that box_below (<<|) and box_above (|>>) have analogs for
> other data types while these functions don't.

I think we should take this comment seriously and deprecate those
operators, so the patch removes them from the documentation.

> 4. Just for extra fun, these point operators are listed in some
> GIST and SP-GIST opclasses; though the box ones are not, as per
> that code comment.

It also updates the operator classes to support the new operators
instead of former ones.  I don't think there are many users of them to
notice the change.

I am adding this to the next commitfest.

Attachment

Re: Bogus documentation for bogus geometric operators

From
Michael Paquier
Date:
On Fri, Aug 21, 2020 at 12:00:45PM +0100, Emre Hasegeli wrote:
> I prepared a patch to add <<| and |>> operators for points to
> deprecate the previous ones.

Emre, the CF bot complains that this does not apply anymore, so please
provide a rebase.  By the way, I am a bit confused to see a patch
that adds new operators on a thread whose subject is about
documentation.
--
Michael

Attachment

Re: Bogus documentation for bogus geometric operators

From
Emre Hasegeli
Date:
> Emre, the CF bot complains that this does not apply anymore, so please
> provide a rebase.  By the way, I am a bit confused to see a patch
> that adds new operators on a thread whose subject is about
> documentation.

Rebased version is attached.

The subject is about the documentation, but the post reveals
inconsistencies of the operators.  Tom Lane fixed the documentation on
the back branches.  The new patch is to fix the operators on the
master only.

Attachment

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
 
The subject is about the documentation, but the post reveals
inconsistencies of the operators.  Tom Lane fixed the documentation on
the back branches.  The new patch is to fix the operators on the
master only.

Nice catch, thanks!
I agree that different operators should not have the same name and I'm planning to review the patch soon. What are your ideas on the possibility to backpatch it also? It seems a little bit weird that the operator can change its name between versions of PG. 
--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
 Emre, could you please again rebase your patch on top of 2f70fdb0644c32c4154236c2b5c241bec92eac5e ?
 It is not applied anymore.


--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
Emre, 

I've rebased and tested your proposed patch. It seems fine and sensible to me.
I have only one thing to note: as this patch doesn't disable <^ and >^ operator for boxes the existing state of documentation seem consistent to me:

select '((0,0),(1,1))'::box <<| '((0,1),(1,2))'::box; 
----------
 f

select '((0,0),(1,1))'::box <^ '((0,1),(1,2))'::box;
----------
 t

So I've only reverted the changes in the documentation on geometric functions in your patch.
PFA v3 of your patch. I'd mark it ready to commit if you agree.

Thank you!

--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com
Attachment

Re: Bogus documentation for bogus geometric operators

From
Emre Hasegeli
Date:
> I've rebased and tested your proposed patch. It seems fine and sensible to me.

Thanks

> I have only one thing to note: as this patch doesn't disable <^ and >^ operator for boxes the existing state of
documentationseem consistent to me:
 
>
> select '((0,0),(1,1))'::box <<| '((0,1),(1,2))'::box;
> ----------
>  f
>
> select '((0,0),(1,1))'::box <^ '((0,1),(1,2))'::box;
> ----------
>  t
>
> So I've only reverted the changes in the documentation on geometric functions in your patch.

You are right.  We need to keep the documentation for box operators,
but remove the lines for the point operators.



Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
> I have only one thing to note: as this patch doesn't disable <^ and >^ operator for boxes the existing state of documentation seem consistent to me:
>
> select '((0,0),(1,1))'::box <<| '((0,1),(1,2))'::box;
> ----------
>  f
>
> select '((0,0),(1,1))'::box <^ '((0,1),(1,2))'::box;
> ----------
>  t
>
> So I've only reverted the changes in the documentation on geometric functions in your patch.

You are right.  We need to keep the documentation for box operators,
but remove the lines for the point operators.

Indeed you are right. PFA v4 with documentation removed for <^ and >^ for point
Thanks!

--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com
Attachment

Re: Bogus documentation for bogus geometric operators

From
Tom Lane
Date:
Pavel Borisov <pashkin.elfe@gmail.com> writes:
> [ v4-0001-Deprecate-and-replace-and-operators-for-points.patch ]

I made a cursory pass over this, and two things stood out to me:

1. The patch removes <^ and >^ from func.sgml, which is fine, but
shouldn't there be an addition for the new operators?  (I think
probably this need only be an addition of "point" as a possible
input type for <<| and |>>.)  Actually, as long we're not completely
removing these operators, I'm not sure it's okay to make them completely
undocumented.  Maybe instead of removing, change the text to be
"Deprecated, use the equivalent XXX operator instead."  Or we could
add a footnote similar to what was there for a previous renaming:

    Note

    Before PostgreSQL 8.2, the containment operators @> and <@ were
    respectively called ~ and @. These names are still available, but
    are deprecated and will eventually be removed.

2. I'm a bit queasy about removing these operators from the opclasses.
I'm not sure anyone will thank us for "the operator is still there, so
your query is still accepted, but it runs 1000X slower than before".
It seems like more plausible answers are either "nuke the operators
entirely, force people to change their queries now" or else "support
both old and new names in the opclasses for awhile to come".  In
previous operator renamings we've generally followed the second path,
so that's what I'm inclined to think should happen here.

            regards, tom lane



Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
1. The patch removes <^ and >^ from func.sgml, which is fine, but 
shouldn't there be an addition for the new operators?  (I think
I fully agree and added "point" as a possible input type for <<| and |>> in manual. PFA v5
 
undocumented.  Maybe instead of removing, change the text to be
"Deprecated, use the equivalent XXX operator instead."  Or we could
add a footnote similar to what was there for a previous renaming:
The problem that this new <<| is equivalent to <^ only for points (To recap: the source of a problem is the same name of <^  operator for points and boxes with different meaning for these types). 

                               point                                                                                       box
<<| |>>          strictly above/below  (new)                                                strictly above/below 
<^ >^             strictly above/below (deprecated, but available)               above/below

So it seems to me that trying to mention the subtle difference of deprecated operator to same-named one for different data type inevitably make things much worse for reader. On this reason I'd vote for complete nuking <^ for point type (but this is not the only way so I haven't done this in v5).

What do you think?

--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com
Attachment

Re: Bogus documentation for bogus geometric operators

From
Tom Lane
Date:
Pavel Borisov <pashkin.elfe@gmail.com> writes:
>> undocumented.  Maybe instead of removing, change the text to be
>> "Deprecated, use the equivalent XXX operator instead."  Or we could
>> add a footnote similar to what was there for a previous renaming:

> The problem that this new <<| is equivalent to <^ only for points (To
> recap: the source of a problem is the same name of <^  operator for points
> and boxes with different meaning for these types).

I don't think it's that hard to be clear; see proposed wording below.

The other loose end is that I don't think we can take away the opclass
entries for the old spellings, unless we're willing to visibly break
people's queries by removing those operator names altogether.  That
doesn't seem like it'll fly when we haven't even deprecated the old
names yet.  So for now, we have to support both names in the opclasses.
I extended the patch to do that.

This version seems committable to me --- any thoughts?

            regards, tom lane

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 7d06b979eb..507bc1a668 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -10609,7 +10609,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
        </para>
        <para>
         Is first object strictly below second?
-        Available for <type>box</type>, <type>polygon</type>,
+        Available for <type>point</type>, <type>box</type>, <type>polygon</type>,
         <type>circle</type>.
        </para>
        <para>
@@ -10625,7 +10625,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
        </para>
        <para>
         Is first object strictly above second?
-        Available for <type>box</type>, <type>polygon</type>,
+        Available for <type>point</type>, <type>box</type>, <type>polygon</type>,
         <type>circle</type>.
        </para>
        <para>
@@ -10680,21 +10680,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
        </para></entry>
       </row>

-      <row>
-       <entry role="func_table_entry"><para role="func_signature">
-        <type>point</type> <literal><^</literal> <type>point</type>
-        <returnvalue>boolean</returnvalue>
-       </para>
-       <para>
-        Is first object strictly below second?
-        (This operator is misnamed; it should be <literal><<|</literal>.)
-       </para>
-       <para>
-        <literal>point '(1,0)' <^ point '(1,1)'</literal>
-        <returnvalue>t</returnvalue>
-       </para></entry>
-      </row>
-
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <type>box</type> <literal>>^</literal> <type>box</type>
@@ -10709,21 +10694,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
        </para></entry>
       </row>

-      <row>
-       <entry role="func_table_entry"><para role="func_signature">
-        <type>point</type> <literal>>^</literal> <type>point</type>
-        <returnvalue>boolean</returnvalue>
-       </para>
-       <para>
-        Is first object strictly above second?
-        (This operator is misnamed; it should be <literal>|>></literal>.)
-       </para>
-       <para>
-        <literal>point '(1,1)' >^ point '(1,0)'</literal>
-        <returnvalue>t</returnvalue>
-       </para></entry>
-      </row>
-
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <replaceable>geometric_type</replaceable> <literal>?#</literal> <replaceable>geometric_type</replaceable>
@@ -10877,6 +10847,18 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
     </para>
    </caution>

+   <note>
+    <para>
+     Before <productname>PostgreSQL</productname> 14, the point
+     is strictly below/above comparison operators <type>point</type>
+     <literal><<|</literal> <type>point</type> and <type>point</type>
+     <literal>|>></literal> <type>point</type> were respectively
+     called <literal><^</literal> and <literal>>^</literal>.  These
+     names are still available, but are deprecated and will eventually be
+     removed.
+    </para>
+   </note>
+
    <table id="functions-geometry-func-table">
     <title>Geometric Functions</title>
     <tgroup cols="1">
diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml
index 1bf5f09659..d1b6cc9a01 100644
--- a/doc/src/sgml/gist.sgml
+++ b/doc/src/sgml/gist.sgml
@@ -118,12 +118,12 @@

      <row>
       <entry valign="middle" morerows="7"><literal>point_ops</literal></entry>
-      <entry><literal>>^ (point,point)</literal></entry>
+      <entry><literal>|>> (point,point)</literal></entry>
       <entry valign="middle" morerows="7"><literal><-> (point,point)</literal></entry>
      </row>
      <row><entry><literal><< (point,point)</literal></entry></row>
      <row><entry><literal>>> (point,point)</literal></entry></row>
-     <row><entry><literal><^ (point,point)</literal></entry></row>
+     <row><entry><literal><<| (point,point)</literal></entry></row>
      <row><entry><literal>~= (point,point)</literal></entry></row>
      <row><entry><literal><@ (point,box)</literal></entry></row>
      <row><entry><literal><@ (point,polygon)</literal></entry></row>
diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml
index 68d09951d9..ea88ae45e5 100644
--- a/doc/src/sgml/spgist.sgml
+++ b/doc/src/sgml/spgist.sgml
@@ -76,7 +76,7 @@
      <row>
       <entry valign="middle" morerows="11"><literal>box_ops</literal></entry>
       <entry><literal><< (box,box)</literal></entry>
-      <entry valign="middle" morerows="11"><literal><-> (box,point)</literal></entry>
+      <entry valign="middle" morerows="11"><literal><-> (box,point)</literal></entry>
      </row>
      <row><entry><literal>&< (box,box)</literal></entry></row>
      <row><entry><literal>&> (box,box)</literal></entry></row>
@@ -92,12 +92,12 @@

      <row>
       <entry valign="middle" morerows="5"><literal>kd_point_ops</literal></entry>
-      <entry><literal>>^ (point,point)</literal></entry>
+      <entry><literal>|>> (point,point)</literal></entry>
       <entry valign="middle" morerows="5"><literal><-> (point,point)</literal></entry>
      </row>
      <row><entry><literal><< (point,point)</literal></entry></row>
      <row><entry><literal>>> (point,point)</literal></entry></row>
-     <row><entry><literal><^ (point,point)</literal></entry></row>
+     <row><entry><literal><<| (point,point)</literal></entry></row>
      <row><entry><literal>~= (point,point)</literal></entry></row>
      <row><entry><literal><@ (point,box)</literal></entry></row>

@@ -132,16 +132,16 @@
      <row><entry><literal><<| (polygon,polygon)</literal></entry></row>
      <row><entry><literal>&<| (polygon,polygon)</literal></entry></row>
      <row><entry><literal>|>> (polygon,polygon)</literal></entry></row>
-     <row><entry><literal>|&> (polygon,polygon)</literal></entry></row>
+     <row><entry><literal>|&> (polygon,polygon)</literal></entry></row>

      <row>
       <entry valign="middle" morerows="5"><literal>quad_point_ops</literal></entry>
-      <entry><literal>>^ (point,point)</literal></entry>
+      <entry><literal>|>> (point,point)</literal></entry>
       <entry valign="middle" morerows="5"><literal><-> (point,point)</literal></entry>
      </row>
      <row><entry><literal><< (point,point)</literal></entry></row>
      <row><entry><literal>>> (point,point)</literal></entry></row>
-     <row><entry><literal><^ (point,point)</literal></entry></row>
+     <row><entry><literal><<| (point,point)</literal></entry></row>
      <row><entry><literal>~= (point,point)</literal></entry></row>
      <row><entry><literal><@ (point,box)</literal></entry></row>

@@ -159,7 +159,7 @@
      <row><entry><literal>&< (anyrange,anyrange)</literal></entry></row>
      <row><entry><literal>&> (anyrange,anyrange)</literal></entry></row>
      <row><entry><literal>-|- (anyrange,anyrange)</literal></entry></row>
-
+
      <row>
       <entry valign="middle" morerows="9"><literal>text_ops</literal></entry>
       <entry><literal>= (text,text)</literal></entry>
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index b03c4b55a0..784807c636 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -1341,8 +1341,18 @@ gist_point_consistent(PG_FUNCTION_ARGS)
     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
     bool        result;
-    StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;
+    StrategyNumber strategyGroup;
+
+    /*
+     * We have to remap these strategy numbers to get this klugy
+     * classification logic to work.
+     */
+    if (strategy == RTOldBelowStrategyNumber)
+        strategy = RTBelowStrategyNumber;
+    else if (strategy == RTOldAboveStrategyNumber)
+        strategy = RTAboveStrategyNumber;

+    strategyGroup = strategy / GeoStrategyNumberOffset;
     switch (strategyGroup)
     {
         case PointStrategyNumberGroup:
diff --git a/src/backend/access/spgist/spgkdtreeproc.c b/src/backend/access/spgist/spgkdtreeproc.c
index bee30153f7..6581238cef 100644
--- a/src/backend/access/spgist/spgkdtreeproc.c
+++ b/src/backend/access/spgist/spgkdtreeproc.c
@@ -209,10 +209,12 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS)
                 }
                 break;
             case RTBelowStrategyNumber:
+            case RTOldBelowStrategyNumber:
                 if ((in->level % 2) == 0 && FPlt(query->y, coord))
                     which &= (1 << 1);
                 break;
             case RTAboveStrategyNumber:
+            case RTOldAboveStrategyNumber:
                 if ((in->level % 2) == 0 && FPgt(query->y, coord))
                     which &= (1 << 2);
                 break;
diff --git a/src/backend/access/spgist/spgquadtreeproc.c b/src/backend/access/spgist/spgquadtreeproc.c
index b4451cc1ae..249b3828fe 100644
--- a/src/backend/access/spgist/spgquadtreeproc.c
+++ b/src/backend/access/spgist/spgquadtreeproc.c
@@ -316,10 +316,12 @@ spg_quad_inner_consistent(PG_FUNCTION_ARGS)
                 which &= (1 << getQuadrant(centroid, query));
                 break;
             case RTBelowStrategyNumber:
+            case RTOldBelowStrategyNumber:
                 if (SPTEST(point_above, centroid, query))
                     which &= (1 << 2) | (1 << 3);
                 break;
             case RTAboveStrategyNumber:
+            case RTOldAboveStrategyNumber:
                 if (SPTEST(point_below, centroid, query))
                     which &= (1 << 1) | (1 << 4);
                 break;
@@ -434,9 +436,11 @@ spg_quad_leaf_consistent(PG_FUNCTION_ARGS)
                 res = SPTEST(point_eq, datum, query);
                 break;
             case RTBelowStrategyNumber:
+            case RTOldBelowStrategyNumber:
                 res = SPTEST(point_below, datum, query);
                 break;
             case RTAboveStrategyNumber:
+            case RTOldAboveStrategyNumber:
                 res = SPTEST(point_above, datum, query);
                 break;
             case RTContainedByStrategyNumber:
diff --git a/src/include/access/stratnum.h b/src/include/access/stratnum.h
index d280f7e4fc..415e1f7e88 100644
--- a/src/include/access/stratnum.h
+++ b/src/include/access/stratnum.h
@@ -76,8 +76,10 @@ typedef uint16 StrategyNumber;
 #define RTSuperStrategyNumber            26    /* for inet << */
 #define RTSuperEqualStrategyNumber        27    /* for inet >>= */
 #define RTPrefixStrategyNumber            28    /* for text ^@ */
+#define RTOldBelowStrategyNumber        29    /* for old spelling of <<| */
+#define RTOldAboveStrategyNumber        30    /* for old spelling of |>> */

-#define RTMaxStrategyNumber                28
+#define RTMaxStrategyNumber                30


 #endif                            /* STRATNUM_H */
diff --git a/src/include/catalog/pg_amop.dat b/src/include/catalog/pg_amop.dat
index c7fee9f3ab..2c899f19d9 100644
--- a/src/include/catalog/pg_amop.dat
+++ b/src/include/catalog/pg_amop.dat
@@ -1111,7 +1111,10 @@

 # gist point_ops
 { amopfamily => 'gist/point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '11', amopopr => '>^(point,point)',
+  amoprighttype => 'point', amopstrategy => '11', amopopr => '|>>(point,point)',
+  amopmethod => 'gist' },
+{ amopfamily => 'gist/point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '30', amopopr => '>^(point,point)',
   amopmethod => 'gist' },
 { amopfamily => 'gist/point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '1', amopopr => '<<(point,point)',
@@ -1120,7 +1123,10 @@
   amoprighttype => 'point', amopstrategy => '5', amopopr => '>>(point,point)',
   amopmethod => 'gist' },
 { amopfamily => 'gist/point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '10', amopopr => '<^(point,point)',
+  amoprighttype => 'point', amopstrategy => '10', amopopr => '<<|(point,point)',
+  amopmethod => 'gist' },
+{ amopfamily => 'gist/point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '29', amopopr => '<^(point,point)',
   amopmethod => 'gist' },
 { amopfamily => 'gist/point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '6', amopopr => '~=(point,point)',
@@ -1370,7 +1376,10 @@

 # SP-GiST quad_point_ops
 { amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '11', amopopr => '>^(point,point)',
+  amoprighttype => 'point', amopstrategy => '11', amopopr => '|>>(point,point)',
+  amopmethod => 'spgist' },
+{ amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '30', amopopr => '>^(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '1', amopopr => '<<(point,point)',
@@ -1379,7 +1388,10 @@
   amoprighttype => 'point', amopstrategy => '5', amopopr => '>>(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '10', amopopr => '<^(point,point)',
+  amoprighttype => 'point', amopstrategy => '10', amopopr => '<<|(point,point)',
+  amopmethod => 'spgist' },
+{ amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '29', amopopr => '<^(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '6', amopopr => '~=(point,point)',
@@ -1394,7 +1406,10 @@

 # SP-GiST kd_point_ops
 { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '11', amopopr => '>^(point,point)',
+  amoprighttype => 'point', amopstrategy => '11', amopopr => '|>>(point,point)',
+  amopmethod => 'spgist' },
+{ amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '30', amopopr => '>^(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '1', amopopr => '<<(point,point)',
@@ -1403,7 +1418,10 @@
   amoprighttype => 'point', amopstrategy => '5', amopopr => '>>(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
-  amoprighttype => 'point', amopstrategy => '10', amopopr => '<^(point,point)',
+  amoprighttype => 'point', amopstrategy => '10', amopopr => '<<|(point,point)',
+  amopmethod => 'spgist' },
+{ amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
+  amoprighttype => 'point', amopstrategy => '29', amopopr => '<^(point,point)',
   amopmethod => 'spgist' },
 { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point',
   amoprighttype => 'point', amopstrategy => '6', amopopr => '~=(point,point)',
diff --git a/src/include/catalog/pg_operator.dat b/src/include/catalog/pg_operator.dat
index b3f5645977..7ae19235ee 100644
--- a/src/include/catalog/pg_operator.dat
+++ b/src/include/catalog/pg_operator.dat
@@ -395,7 +395,7 @@
   oprname => '<=', oprleft => 'box', oprright => 'box', oprresult => 'bool',
   oprcom => '>=(box,box)', oprnegate => '>(box,box)', oprcode => 'box_le',
   oprrest => 'areasel', oprjoin => 'areajoinsel' },
-{ oid => '506', descr => 'is above',
+{ oid => '506', descr => 'deprecated, use |>> instead',
   oprname => '>^', oprleft => 'point', oprright => 'point', oprresult => 'bool',
   oprcode => 'point_above', oprrest => 'positionsel',
   oprjoin => 'positionjoinsel' },
@@ -407,7 +407,7 @@
   oprname => '>>', oprleft => 'point', oprright => 'point', oprresult => 'bool',
   oprcode => 'point_right', oprrest => 'positionsel',
   oprjoin => 'positionjoinsel' },
-{ oid => '509', descr => 'is below',
+{ oid => '509', descr => 'deprecated, use <<| instead',
   oprname => '<^', oprleft => 'point', oprright => 'point', oprresult => 'bool',
   oprcode => 'point_below', oprrest => 'positionsel',
   oprjoin => 'positionjoinsel' },
@@ -1878,6 +1878,15 @@
   oprname => '#', oprleft => 'line', oprright => 'line', oprresult => 'point',
   oprcom => '#(line,line)', oprcode => 'line_interpt' },

+{ oid => '4161', descr => 'is above',
+  oprname => '|>>', oprleft => 'point', oprright => 'point',
+  oprresult => 'bool', oprcode => 'point_above', oprrest => 'positionsel',
+  oprjoin => 'positionjoinsel' },
+{ oid => '4162', descr => 'is below',
+  oprname => '<<|', oprleft => 'point', oprright => 'point',
+  oprresult => 'bool', oprcode => 'point_below', oprrest => 'positionsel',
+  oprjoin => 'positionjoinsel' },
+
 # MACADDR type
 { oid => '1220', descr => 'equal',
   oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'macaddr',
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 76679bae8d..18bb92b810 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -160,13 +160,13 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
      4
 (1 row)

-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';
  count
 -------
      1
 (1 row)

-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';
  count
 -------
      5
@@ -470,30 +470,30 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';
                       QUERY PLAN
 ------------------------------------------------------
  Aggregate
    ->  Index Only Scan using gpointind on point_tbl p
-         Index Cond: (f1 <^ '(0,0)'::point)
+         Index Cond: (f1 <<| '(0,0)'::point)
 (3 rows)

-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';
  count
 -------
      1
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';
                       QUERY PLAN
 ------------------------------------------------------
  Aggregate
    ->  Index Only Scan using gpointind on point_tbl p
-         Index Cond: (f1 >^ '(0,0)'::point)
+         Index Cond: (f1 |>> '(0,0)'::point)
 (3 rows)

-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';
  count
 -------
      5
diff --git a/src/test/regress/expected/create_index_spgist.out b/src/test/regress/expected/create_index_spgist.out
index 1dd110dfc5..afe38e16a2 100644
--- a/src/test/regress/expected/create_index_spgist.out
+++ b/src/test/regress/expected/create_index_spgist.out
@@ -62,13 +62,13 @@ SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';
   4999
 (1 row)

-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
  count
 -------
   5000
 (1 row)

-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
  count
 -------
   5999
@@ -282,30 +282,30 @@ SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
                         QUERY PLAN
 -----------------------------------------------------------
  Aggregate
    ->  Index Only Scan using sp_quad_ind on quad_point_tbl
-         Index Cond: (p <^ '(5000,4000)'::point)
+         Index Cond: (p <<| '(5000,4000)'::point)
 (3 rows)

-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
  count
 -------
   5000
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
                         QUERY PLAN
 -----------------------------------------------------------
  Aggregate
    ->  Index Only Scan using sp_quad_ind on quad_point_tbl
-         Index Cond: (p >^ '(5000,4000)'::point)
+         Index Cond: (p |>> '(5000,4000)'::point)
 (3 rows)

-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
  count
 -------
   5999
@@ -449,30 +449,30 @@ SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
                       QUERY PLAN
 -------------------------------------------------------
  Aggregate
    ->  Index Only Scan using sp_kd_ind on kd_point_tbl
-         Index Cond: (p <^ '(5000,4000)'::point)
+         Index Cond: (p <<| '(5000,4000)'::point)
 (3 rows)

-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
  count
 -------
   5000
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
                       QUERY PLAN
 -------------------------------------------------------
  Aggregate
    ->  Index Only Scan using sp_kd_ind on kd_point_tbl
-         Index Cond: (p >^ '(5000,4000)'::point)
+         Index Cond: (p |>> '(5000,4000)'::point)
 (3 rows)

-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
  count
 -------
   5999
@@ -897,34 +897,34 @@ SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
-                      QUERY PLAN
--------------------------------------------------------
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
+                       QUERY PLAN
+--------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on quad_point_tbl
-         Recheck Cond: (p <^ '(5000,4000)'::point)
+         Recheck Cond: (p <<| '(5000,4000)'::point)
          ->  Bitmap Index Scan on sp_quad_ind
-               Index Cond: (p <^ '(5000,4000)'::point)
+               Index Cond: (p <<| '(5000,4000)'::point)
 (5 rows)

-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
  count
 -------
   5000
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
-                      QUERY PLAN
--------------------------------------------------------
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
+                       QUERY PLAN
+--------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on quad_point_tbl
-         Recheck Cond: (p >^ '(5000,4000)'::point)
+         Recheck Cond: (p |>> '(5000,4000)'::point)
          ->  Bitmap Index Scan on sp_quad_ind
-               Index Cond: (p >^ '(5000,4000)'::point)
+               Index Cond: (p |>> '(5000,4000)'::point)
 (5 rows)

-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
  count
 -------
   5999
@@ -1016,34 +1016,34 @@ SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
-                      QUERY PLAN
--------------------------------------------------------
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
+                       QUERY PLAN
+--------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on kd_point_tbl
-         Recheck Cond: (p <^ '(5000,4000)'::point)
+         Recheck Cond: (p <<| '(5000,4000)'::point)
          ->  Bitmap Index Scan on sp_kd_ind
-               Index Cond: (p <^ '(5000,4000)'::point)
+               Index Cond: (p <<| '(5000,4000)'::point)
 (5 rows)

-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
  count
 -------
   5000
 (1 row)

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
-                      QUERY PLAN
--------------------------------------------------------
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
+                       QUERY PLAN
+--------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on kd_point_tbl
-         Recheck Cond: (p >^ '(5000,4000)'::point)
+         Recheck Cond: (p |>> '(5000,4000)'::point)
          ->  Bitmap Index Scan on sp_kd_ind
-               Index Cond: (p >^ '(5000,4000)'::point)
+               Index Cond: (p |>> '(5000,4000)'::point)
 (5 rows)

-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
  count
 -------
   5999
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 7ed29b4961..3b39137400 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -1985,8 +1985,6 @@ ORDER BY 1, 2, 3;
         783 |            8 | <@
         783 |            9 | &<|
         783 |           10 | <<|
-        783 |           10 | <^
-        783 |           11 | >^
         783 |           11 | |>>
         783 |           12 | |&>
         783 |           15 | <->
@@ -2002,6 +2000,8 @@ ORDER BY 1, 2, 3;
         783 |           26 | >>
         783 |           27 | >>=
         783 |           28 | <@
+        783 |           29 | <^
+        783 |           30 | >^
         783 |           48 | <@
         783 |           68 | <@
        2742 |            1 | &&
@@ -2060,9 +2060,7 @@ ORDER BY 1, 2, 3;
        4000 |            8 | <@
        4000 |            9 | &<|
        4000 |           10 | <<|
-       4000 |           10 | <^
        4000 |           11 | <
-       4000 |           11 | >^
        4000 |           11 | |>>
        4000 |           12 | <=
        4000 |           12 | |&>
@@ -2081,6 +2079,8 @@ ORDER BY 1, 2, 3;
        4000 |           26 | >>
        4000 |           27 | >>=
        4000 |           28 | ^@
+       4000 |           29 | <^
+       4000 |           30 | >^
 (123 rows)

 -- Check that all opclass search operators have selectivity estimators.
diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out
index 77e250fc3e..1fa9d7ce2c 100644
--- a/src/test/regress/expected/point.out
+++ b/src/test/regress/expected/point.out
@@ -69,14 +69,14 @@ SELECT '' AS three, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >> p.f1;
 (3 rows)

 -- above
-SELECT '' AS one, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >^ p.f1;
+SELECT '' AS one, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' |>> p.f1;
  one |    f1
 -----+----------
      | (-5,-12)
 (1 row)

 -- below
-SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 <<| '(0.0, 0.0)';
  one |    f1
 -----+----------
      | (-5,-12)
@@ -412,7 +412,7 @@ SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS dis
 -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10
 SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance
    FROM POINT_TBL p1, POINT_TBL p2
-   WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1
+   WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 |>> p2.f1
    ORDER BY distance;
  three |      point1       |      point2       |     distance
 -------+-------------------+-------------------+------------------
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index b27643cad6..55326eb47b 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -136,9 +136,9 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';

 SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';

-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';

-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';

 SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';

@@ -220,12 +220,12 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
 SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
-SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
-SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)';

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
diff --git a/src/test/regress/sql/create_index_spgist.sql b/src/test/regress/sql/create_index_spgist.sql
index 68632e3732..bff5f2d092 100644
--- a/src/test/regress/sql/create_index_spgist.sql
+++ b/src/test/regress/sql/create_index_spgist.sql
@@ -46,9 +46,9 @@ SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)';

 SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';

-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';

-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';

 SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)';

@@ -126,12 +126,12 @@ SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';
 SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)';
@@ -184,12 +184,12 @@ SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';
 SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)';
@@ -320,12 +320,12 @@ SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';
 SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
-SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
-SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';
+SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)';
@@ -348,12 +348,12 @@ SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';
 SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
-SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)';

 EXPLAIN (COSTS OFF)
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
-SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';
+SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)';

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)';
diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql
index 6a1ca12d5c..41366fb6b7 100644
--- a/src/test/regress/sql/point.sql
+++ b/src/test/regress/sql/point.sql
@@ -48,10 +48,10 @@ SELECT '' AS three, p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)';
 SELECT '' AS three, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >> p.f1;

 -- above
-SELECT '' AS one, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >^ p.f1;
+SELECT '' AS one, p.* FROM POINT_TBL p WHERE '(0.0,0.0)' |>> p.f1;

 -- below
-SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 <<| '(0.0, 0.0)';

 -- equal
 SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 ~= '(5.1, 34.5)';
@@ -93,7 +93,7 @@ SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS dis
 -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10
 SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance
    FROM POINT_TBL p1, POINT_TBL p2
-   WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1
+   WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 |>> p2.f1
    ORDER BY distance;

 -- Test that GiST indexes provide same behavior as sequential scan

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
>> undocumented.  Maybe instead of removing, change the text to be
>> "Deprecated, use the equivalent XXX operator instead."  Or we could
>> add a footnote similar to what was there for a previous renaming:

> The problem that this new <<| is equivalent to <^ only for points (To
> recap: the source of a problem is the same name of <^  operator for points
> and boxes with different meaning for these types).

I don't think it's that hard to be clear; see proposed wording below.

The other loose end is that I don't think we can take away the opclass
entries for the old spellings, unless we're willing to visibly break
people's queries by removing those operator names altogether.  That
doesn't seem like it'll fly when we haven't even deprecated the old
names yet.  So for now, we have to support both names in the opclasses.
I extended the patch to do that.

This version seems committable to me --- any thoughts?
The wording seems no problem to me. I  looked into a patch and changes also seem sensible but I can not apply this patch because of really many rejects. Which commit should I use to apply it onto?

--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
The wording seems no problem to me. I  looked into a patch and changes also seem sensible but I can not apply this patch because of really many rejects. Which commit should I use to apply it onto?
Sorry, the rejects were due to my git configuration. I will apply and make the final checks soon.


--
Best regards,
Pavel Borisov

Postgres Professional: http://postgrespro.com

Re: Bogus documentation for bogus geometric operators

From
Pavel Borisov
Date:
The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:       tested, passed
Spec compliant:           not tested
Documentation:            tested, passed

I've made another check of the final state and suppose it is ready to be pushed.

Pavel Borisov

Re: Bogus documentation for bogus geometric operators

From
Tom Lane
Date:
Pavel Borisov <pashkin.elfe@gmail.com> writes:
> I've made another check of the final state and suppose it is ready to be pushed.

Sounds good, pushed.

            regards, tom lane