From 9af891b75fa14719eb9d59cf3649061e31fc3d6c Mon Sep 17 00:00:00 2001
From: Emre Hasegeli <emre@hasegeli.com>
Date: Wed, 31 Aug 2016 09:58:18 +0200
Subject: [PATCH] inet-contain-op-v3

---
 doc/src/sgml/brin.sgml                   | 14 +++--
 doc/src/sgml/func.sgml                   | 35 ++++++++-----
 doc/src/sgml/gist.sgml                   | 16 +++---
 doc/src/sgml/spgist.sgml                 | 16 +++---
 src/backend/utils/adt/network_gist.c     | 12 +++++
 src/backend/utils/adt/network_selfuncs.c |  8 ++-
 src/backend/utils/adt/network_spgist.c   |  4 ++
 src/include/access/stratnum.h            |  4 +-
 src/include/catalog/pg_amop.h            | 24 ++++++---
 src/include/catalog/pg_operator.h        | 26 +++++++---
 src/test/regress/expected/brin.out       | 52 +++++++++++++------
 src/test/regress/expected/inet.out       | 88 +++++++++++++++++++++++++++-----
 src/test/regress/expected/opr_sanity.out | 15 ++++--
 src/test/regress/sql/brin.sql            | 52 +++++++++++++------
 src/test/regress/sql/inet.sql            | 24 ++++++---
 15 files changed, 288 insertions(+), 102 deletions(-)

diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml
index f519285..508bbce 100644
--- a/doc/src/sgml/brin.sgml
+++ b/doc/src/sgml/brin.sgml
@@ -230,29 +230,33 @@
      <entry><type>inet</type></entry>
      <entry>
       <literal>&lt;</literal>
       <literal>&lt;=</literal>
       <literal>=</literal>
       <literal>&gt;=</literal>
       <literal>&gt;</literal>
      </entry>
     </row>
     <row>
-     <entry><literal>network_inclusion_ops</literal></entry>
+     <entry><literal>inet_inclusion_ops</literal></entry>
      <entry><type>inet</type></entry>
      <entry>
-      <literal>&amp;&amp;</>
-      <literal>&gt;&gt;=</>
-      <literal>&lt;&lt;=</literal>
+      <literal>&amp;&amp;</literal>
+      <literal>@&gt;</literal>
+      <literal>&lt;@</literal>
+      <literal>@&gt;&gt;</literal>
+      <literal>&lt;&lt;@</literal>
       <literal>=</literal>
-      <literal>&gt;&gt;</>
       <literal>&lt;&lt;</literal>
+      <literal>&lt;&lt;=</literal>
+      <literal>&gt;&gt;</literal>
+      <literal>&gt;&gt;=</literal>
      </entry>
     </row>
     <row>
      <entry><literal>int4_minmax_ops</literal></entry>
      <entry><type>integer</type></entry>
      <entry>
       <literal>&lt;</literal>
       <literal>&lt;=</literal>
       <literal>=</literal>
       <literal>&gt;=</literal>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 2e64cc4..0f003ef 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -8913,38 +8913,38 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
         <entry> <literal>&gt;</literal> </entry>
         <entry>is greater than</entry>
         <entry><literal>inet '192.168.1.5' &gt; inet '192.168.1.4'</literal></entry>
        </row>
        <row>
         <entry> <literal>&lt;&gt;</literal> </entry>
         <entry>is not equal</entry>
         <entry><literal>inet '192.168.1.5' &lt;&gt; inet '192.168.1.4'</literal></entry>
        </row>
        <row>
-        <entry> <literal>&lt;&lt;</literal> </entry>
-        <entry>is contained by</entry>
-        <entry><literal>inet '192.168.1.5' &lt;&lt; inet '192.168.1/24'</literal></entry>
+        <entry> <literal>&lt;&lt;@</literal> </entry>
+        <entry>is contained by and smaller network</entry>
+        <entry><literal>inet '192.168.1.5' &lt;&lt;@ inet '192.168.1/24'</literal></entry>
        </row>
        <row>
-        <entry> <literal>&lt;&lt;=</literal> </entry>
-        <entry>is contained by or equals</entry>
-        <entry><literal>inet '192.168.1/24' &lt;&lt;= inet '192.168.1/24'</literal></entry>
+        <entry> <literal>&lt;@</literal> </entry>
+        <entry>is contained by (can have the same masklen)</entry>
+        <entry><literal>inet '192.168.1/24' &lt;@ inet '192.168.1/24'</literal></entry>
        </row>
        <row>
-        <entry> <literal>&gt;&gt;</literal> </entry>
-        <entry>contains</entry>
-        <entry><literal>inet '192.168.1/24' &gt;&gt; inet '192.168.1.5'</literal></entry>
+        <entry> <literal>@&gt;&gt;</literal> </entry>
+        <entry>contains and bigger network</entry>
+        <entry><literal>inet '192.168.1/24' @&gt;&gt; inet '192.168.1.5'</literal></entry>
        </row>
        <row>
-        <entry> <literal>&gt;&gt;=</literal> </entry>
-        <entry>contains or equals</entry>
-        <entry><literal>inet '192.168.1/24' &gt;&gt;= inet '192.168.1/24'</literal></entry>
+        <entry> <literal>@&gt;</literal> </entry>
+        <entry>contains (can have the same masklen)</entry>
+        <entry><literal>inet '192.168.1/24' @&gt; inet '192.168.1/24'</literal></entry>
        </row>
        <row>
         <entry> <literal>&amp;&amp;</literal> </entry>
         <entry>contains or is contained by</entry>
         <entry><literal>inet '192.168.1/24' &amp;&amp; inet '192.168.1.80/28'</literal></entry>
        </row>
        <row>
         <entry> <literal>~</literal> </entry>
         <entry>bitwise NOT</entry>
         <entry><literal>~ inet '192.168.1.6'</literal></entry>
@@ -8971,20 +8971,31 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
        </row>
        <row>
         <entry> <literal>-</literal> </entry>
         <entry>subtraction</entry>
         <entry><literal>inet '192.168.1.43' - inet '192.168.1.19'</literal></entry>
        </row>
       </tbody>
      </tgroup>
     </table>
 
+   <note>
+    <para>
+     Before <productname>PostgreSQL</productname> 10, the containment
+     operators <literal>&lt;@</>, <literal>@&gt;</>, <literal>&lt;&lt;@</>,
+     and <literal>@&gt;&gt;</> were respectively called
+     <literal>&lt;&lt;=</>, <literal>&gt;&gt;=</>, <literal>&lt;&lt;</>,
+     and <literal>&gt;&gt;</>.  These names are still available, but are
+     deprecated and will eventually be removed.
+    </para>
+   </note>
+
   <para>
    <xref linkend="cidr-inet-functions-table"> shows the functions
    available for use with the <type>cidr</type> and <type>inet</type>
    types.  The <function>abbrev</function>, <function>host</function>,
    and <function>text</function>
    functions are primarily intended to offer alternative display
    formats.
   </para>
 
     <table id="cidr-inet-functions-table">
diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml
index b3cc347..7a2dada 100644
--- a/doc/src/sgml/gist.sgml
+++ b/doc/src/sgml/gist.sgml
@@ -106,30 +106,34 @@
       </entry>
       <entry>
        <literal>&lt;-&gt;</>
       </entry>
      </row>
      <row>
       <entry><literal>inet_ops</></entry>
       <entry><type>inet</>, <type>cidr</></entry>
       <entry>
        <literal>&amp;&amp;</>
-       <literal>&gt;&gt;</>
-       <literal>&gt;&gt;=</>
+       <literal>@&gt;</>
+       <literal>&lt;@</>
+       <literal>@&gt;&gt;</>
+       <literal>&lt;&lt;@</>
+       <literal>=</>
+       <literal>&lt;&gt;</>
        <literal>&gt;</>
        <literal>&gt;=</>
-       <literal>&lt;&gt;</>
-       <literal>&lt;&lt;</>
-       <literal>&lt;&lt;=</>
        <literal>&lt;</>
        <literal>&lt;=</>
-       <literal>=</>
+       <literal>&lt;&lt;</>
+       <literal>&lt;&lt;=</>
+       <literal>&gt;&gt;</>
+       <literal>&gt;&gt;=</>
       </entry>
       <entry>
       </entry>
      </row>
      <row>
       <entry><literal>point_ops</></entry>
       <entry><type>point</></entry>
       <entry>
        <literal>&gt;&gt;</>
        <literal>&gt;^</>
diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml
index cd4a8d0..95ec27d 100644
--- a/doc/src/sgml/spgist.sgml
+++ b/doc/src/sgml/spgist.sgml
@@ -143,30 +143,34 @@
        <literal>~&lt;~</>
        <literal>~&gt;=~</>
        <literal>~&gt;~</>
       </entry>
      </row>
      <row>
       <entry><literal>inet_ops</></entry>
       <entry><type>inet</>, <type>cidr</></entry>
       <entry>
        <literal>&amp;&amp;</>
-       <literal>&gt;&gt;</>
-       <literal>&gt;&gt;=</>
+       <literal>@&gt;</>
+       <literal>&lt;@</>
+       <literal>@&gt;&gt;</>
+       <literal>&lt;&lt;@</>
+       <literal>=</>
+       <literal>&lt;&gt;</>
        <literal>&gt;</>
        <literal>&gt;=</>
-       <literal>&lt;&gt;</>
-       <literal>&lt;&lt;</>
-       <literal>&lt;&lt;=</>
        <literal>&lt;</>
        <literal>&lt;=</>
-       <literal>=</>
+       <literal>&lt;&lt;</>
+       <literal>&lt;&lt;=</>
+       <literal>&gt;&gt;</>
+       <literal>&gt;&gt;=</>
       </entry>
      </row>
     </tbody>
    </tgroup>
   </table>
 
  <para>
   Of the two operator classes for type <type>point</>,
   <literal>quad_point_ops</> is the default.  <literal>kd_point_ops</>
   supports the same operators but uses a different index data structure which
diff --git a/src/backend/utils/adt/network_gist.c b/src/backend/utils/adt/network_gist.c
index 2caff94..c994b92a 100644
--- a/src/backend/utils/adt/network_gist.c
+++ b/src/backend/utils/adt/network_gist.c
@@ -55,23 +55,27 @@
  * Operator strategy numbers used in the GiST inet_ops opclass
  */
 #define INETSTRAT_OVERLAPS		RTOverlapStrategyNumber
 #define INETSTRAT_EQ			RTEqualStrategyNumber
 #define INETSTRAT_NE			RTNotEqualStrategyNumber
 #define INETSTRAT_LT			RTLessStrategyNumber
 #define INETSTRAT_LE			RTLessEqualStrategyNumber
 #define INETSTRAT_GT			RTGreaterStrategyNumber
 #define INETSTRAT_GE			RTGreaterEqualStrategyNumber
 #define INETSTRAT_SUB			RTSubStrategyNumber
+#define INETSTRAT_SUBNET		RTOldContainedByStrategyNumber
 #define INETSTRAT_SUBEQ			RTSubEqualStrategyNumber
+#define INETSTRAT_CONTAINED		RTContainedByStrategyNumber
 #define INETSTRAT_SUP			RTSuperStrategyNumber
+#define INETSTRAT_SUPERNET		RTOldContainsStrategyNumber
 #define INETSTRAT_SUPEQ			RTSuperEqualStrategyNumber
+#define INETSTRAT_CONTAINS		RTContainsStrategyNumber
 
 
 /*
  * Representation of a GiST INET/CIDR index key.  This is not identical to
  * INET/CIDR because we need to keep track of the length of the common address
  * prefix as well as the minimum netmask length.  However, as long as it
  * follows varlena header rules, the core GiST code won't know the difference.
  * For simplicity we always use 1-byte-header varlena format.
  */
 typedef struct GistInetKey
@@ -169,36 +173,40 @@ inet_gist_consistent(PG_FUNCTION_ARGS)
 	 * Check 2: network bit count
 	 *
 	 * Network bit count (ip_bits) helps to check leaves for sub network and
 	 * sup network operators.  At non-leaf nodes, we know every child value
 	 * has ip_bits >= gk_ip_minbits(key), so we can avoid descending in some
 	 * cases too.
 	 */
 	switch (strategy)
 	{
 		case INETSTRAT_SUB:
+		case INETSTRAT_SUBNET:
 			if (GIST_LEAF(ent) && gk_ip_minbits(key) <= ip_bits(query))
 				PG_RETURN_BOOL(false);
 			break;
 
 		case INETSTRAT_SUBEQ:
+		case INETSTRAT_CONTAINED:
 			if (GIST_LEAF(ent) && gk_ip_minbits(key) < ip_bits(query))
 				PG_RETURN_BOOL(false);
 			break;
 
 		case INETSTRAT_SUPEQ:
+		case INETSTRAT_CONTAINS:
 		case INETSTRAT_EQ:
 			if (gk_ip_minbits(key) > ip_bits(query))
 				PG_RETURN_BOOL(false);
 			break;
 
 		case INETSTRAT_SUP:
+		case INETSTRAT_SUPERNET:
 			if (gk_ip_minbits(key) >= ip_bits(query))
 				PG_RETURN_BOOL(false);
 			break;
 	}
 
 	/*
 	 * Check 3: common network bits
 	 *
 	 * Compare available common prefix bits to the query, but not beyond
 	 * either the query's netmask or the minimum netmask among the represented
@@ -210,24 +218,28 @@ inet_gist_consistent(PG_FUNCTION_ARGS)
 	 * network part of the address.
 	 */
 	minbits = Min(gk_ip_commonbits(key), gk_ip_minbits(key));
 	minbits = Min(minbits, ip_bits(query));
 
 	order = bitncmp(gk_ip_addr(key), ip_addr(query), minbits);
 
 	switch (strategy)
 	{
 		case INETSTRAT_SUB:
+		case INETSTRAT_SUBNET:
 		case INETSTRAT_SUBEQ:
+		case INETSTRAT_CONTAINED:
 		case INETSTRAT_OVERLAPS:
 		case INETSTRAT_SUPEQ:
+		case INETSTRAT_CONTAINS:
 		case INETSTRAT_SUP:
+		case INETSTRAT_SUPERNET:
 			PG_RETURN_BOOL(order == 0);
 
 		case INETSTRAT_LT:
 		case INETSTRAT_LE:
 			if (order > 0)
 				PG_RETURN_BOOL(false);
 			if (order < 0 || !GIST_LEAF(ent))
 				PG_RETURN_BOOL(true);
 			break;
 
diff --git a/src/backend/utils/adt/network_selfuncs.c b/src/backend/utils/adt/network_selfuncs.c
index 2e39687..bd369bc 100644
--- a/src/backend/utils/adt/network_selfuncs.c
+++ b/src/backend/utils/adt/network_selfuncs.c
@@ -29,21 +29,21 @@
 
 
 /* Default selectivity for the inet overlap operator */
 #define DEFAULT_OVERLAP_SEL 0.01
 
 /* Default selectivity for the various inclusion operators */
 #define DEFAULT_INCLUSION_SEL 0.005
 
 /* Default selectivity for specified operator */
 #define DEFAULT_SEL(operator) \
-	((operator) == OID_INET_OVERLAP_OP ? \
+	((operator) == OID_INET_OVERLAPS_OP ? \
 	 DEFAULT_OVERLAP_SEL : DEFAULT_INCLUSION_SEL)
 
 /* Maximum number of items to consider in join selectivity calculations */
 #define MAX_CONSIDERED_ELEMS 1024
 
 static Selectivity networkjoinsel_inner(Oid operator,
 					 VariableStatData *vardata1, VariableStatData *vardata2);
 static Selectivity networkjoinsel_semi(Oid operator,
 					VariableStatData *vardata1, VariableStatData *vardata2);
 static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues);
@@ -865,28 +865,32 @@ inet_semi_join_sel(Datum lhs_value,
  * on the exact codes assigned here; but many other places in this file
  * know that they can negate a code to obtain the code for the commutator
  * operator.
  */
 static int
 inet_opr_codenum(Oid operator)
 {
 	switch (operator)
 	{
 		case OID_INET_SUP_OP:
+		case OID_INET_SUPERNET_OP:
 			return -2;
 		case OID_INET_SUPEQ_OP:
+		case OID_INET_CONTAINS_OP:
 			return -1;
-		case OID_INET_OVERLAP_OP:
+		case OID_INET_OVERLAPS_OP:
 			return 0;
+		case OID_INET_CONTAINED_OP:
 		case OID_INET_SUBEQ_OP:
 			return 1;
 		case OID_INET_SUB_OP:
+		case OID_INET_SUBNET_OP:
 			return 2;
 		default:
 			elog(ERROR, "unrecognized operator %u for inet selectivity",
 				 operator);
 	}
 	return 0;					/* unreached, but keep compiler quiet */
 }
 
 /*
  * Comparison function for the subnet inclusion/overlap operators
diff --git a/src/backend/utils/adt/network_spgist.c b/src/backend/utils/adt/network_spgist.c
index a198a83..95c6119 100644
--- a/src/backend/utils/adt/network_spgist.c
+++ b/src/backend/utils/adt/network_spgist.c
@@ -436,37 +436,41 @@ inet_spg_consistent_bitmap(const inet *prefix, int nkeys, ScanKey scankeys,
 		 * too.
 		 *
 		 * This check is less expensive than checking the address bits, so we
 		 * are doing this before, but it has to be done after for the basic
 		 * comparison strategies, because ip_bits only affect their results
 		 * when the common network bits are the same.
 		 */
 		switch (strategy)
 		{
 			case RTSubStrategyNumber:
+			case RTOldContainedByStrategyNumber:
 				if (commonbits <= ip_bits(argument))
 					bitmap &= (1 << 2) | (1 << 3);
 				break;
 
 			case RTSubEqualStrategyNumber:
+			case RTContainedByStrategyNumber:
 				if (commonbits < ip_bits(argument))
 					bitmap &= (1 << 2) | (1 << 3);
 				break;
 
 			case RTSuperStrategyNumber:
+			case RTOldContainsStrategyNumber:
 				if (commonbits == ip_bits(argument) - 1)
 					bitmap &= 1 | (1 << 1);
 				else if (commonbits >= ip_bits(argument))
 					bitmap = 0;
 				break;
 
 			case RTSuperEqualStrategyNumber:
+			case RTContainsStrategyNumber:
 				if (commonbits == ip_bits(argument))
 					bitmap &= 1 | (1 << 1);
 				else if (commonbits > ip_bits(argument))
 					bitmap = 0;
 				break;
 
 			case RTEqualStrategyNumber:
 				if (commonbits < ip_bits(argument))
 					bitmap &= (1 << 2) | (1 << 3);
 				else if (commonbits == ip_bits(argument))
diff --git a/src/include/access/stratnum.h b/src/include/access/stratnum.h
index eabced5..2916815 100644
--- a/src/include/access/stratnum.h
+++ b/src/include/access/stratnum.h
@@ -57,19 +57,19 @@ typedef uint16 StrategyNumber;
 #define RTOldContainedByStrategyNumber	14		/* for old spelling of <@ */
 #define RTKNNSearchStrategyNumber		15		/* for <-> (distance) */
 #define RTContainsElemStrategyNumber	16		/* for range types @> elem */
 #define RTAdjacentStrategyNumber		17		/* for -|- */
 #define RTEqualStrategyNumber			18		/* for = */
 #define RTNotEqualStrategyNumber		19		/* for != */
 #define RTLessStrategyNumber			20		/* for < */
 #define RTLessEqualStrategyNumber		21		/* for <= */
 #define RTGreaterStrategyNumber			22		/* for > */
 #define RTGreaterEqualStrategyNumber	23		/* for >= */
-#define RTSubStrategyNumber				24		/* for inet >> */
+#define RTSubStrategyNumber				24		/* for inet << */
 #define RTSubEqualStrategyNumber		25		/* for inet <<= */
-#define RTSuperStrategyNumber			26		/* for inet << */
+#define RTSuperStrategyNumber			26		/* for inet >> */
 #define RTSuperEqualStrategyNumber		27		/* for inet >>= */
 
 #define RTMaxStrategyNumber				27
 
 
 #endif   /* STRATNUM_H */
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index e4c3515..28f4162 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -842,45 +842,53 @@ DATA(insert (	5000	603  603  7 s	 498	4000 0 ));
 DATA(insert (	5000	603  603  8 s	 497	4000 0 ));
 DATA(insert (	5000	603  603  9 s	2571	4000 0 ));
 DATA(insert (	5000	603  603 10 s	2570	4000 0 ));
 DATA(insert (	5000	603  603 11 s	2573	4000 0 ));
 DATA(insert (	5000	603  603 12 s	2572	4000 0 ));
 
 /*
  * GiST inet_ops
  */
 DATA(insert (	3550	869 869 3 s		3552 783 0 ));
+DATA(insert (	3550	869 869 7 s		3453 783 0 ));
+DATA(insert (	3550	869 869 8 s		3451 783 0 ));
+DATA(insert (	3550	869 869 13 s	3452 783 0 ));
+DATA(insert (	3550	869 869 14 s	3450 783 0 ));
 DATA(insert (	3550	869 869 18 s	1201 783 0 ));
 DATA(insert (	3550	869 869 19 s	1202 783 0 ));
 DATA(insert (	3550	869 869 20 s	1203 783 0 ));
 DATA(insert (	3550	869 869 21 s	1204 783 0 ));
 DATA(insert (	3550	869 869 22 s	1205 783 0 ));
 DATA(insert (	3550	869 869 23 s	1206 783 0 ));
 DATA(insert (	3550	869 869 24 s	931 783 0 ));
 DATA(insert (	3550	869 869 25 s	932 783 0 ));
 DATA(insert (	3550	869 869 26 s	933 783 0 ));
 DATA(insert (	3550	869 869 27 s	934 783 0 ));
 
 /*
  * SP-GiST inet_ops
  */
 DATA(insert (	3794	869 869 3 s		3552 4000 0 ));
+DATA(insert (	3794	869 869 7 s		3453 4000 0 ));
+DATA(insert (	3794	869 869 8 s		3451 4000 0 ));
+DATA(insert (	3794	869 869 13 s	3452 4000 0 ));
+DATA(insert (	3794	869 869 14 s	3450 4000 0 ));
 DATA(insert (	3794	869 869 18 s	1201 4000 0 ));
 DATA(insert (	3794	869 869 19 s	1202 4000 0 ));
 DATA(insert (	3794	869 869 20 s	1203 4000 0 ));
 DATA(insert (	3794	869 869 21 s	1204 4000 0 ));
 DATA(insert (	3794	869 869 22 s	1205 4000 0 ));
 DATA(insert (	3794	869 869 23 s	1206 4000 0 ));
-DATA(insert (	3794	869 869 24 s	931 4000 0 ));
-DATA(insert (	3794	869 869 25 s	932 4000 0 ));
-DATA(insert (	3794	869 869 26 s	933 4000 0 ));
-DATA(insert (	3794	869 869 27 s	934 4000 0 ));
+DATA(insert (	3794	869 869 24 s	931	 4000 0 ));
+DATA(insert (	3794	869 869 25 s	932	 4000 0 ));
+DATA(insert (	3794	869 869 26 s	933	 4000 0 ));
+DATA(insert (	3794	869 869 27 s	934	 4000 0 ));
 
 /* BRIN opclasses */
 /* minmax bytea */
 DATA(insert (	4064	 17   17 1 s	  1957	  3580 0 ));
 DATA(insert (	4064	 17   17 2 s	  1958	  3580 0 ));
 DATA(insert (	4064	 17   17 3 s	  1955	  3580 0 ));
 DATA(insert (	4064	 17   17 4 s	  1960	  3580 0 ));
 DATA(insert (	4064	 17   17 5 s	  1959	  3580 0 ));
 /* minmax "char" */
 DATA(insert (	4062	 18   18 1 s	   631	  3580 0 ));
@@ -1000,25 +1008,29 @@ DATA(insert (	4074	829  829 3 s	  1220	  3580 0 ));
 DATA(insert (	4074	829  829 4 s	  1225	  3580 0 ));
 DATA(insert (	4074	829  829 5 s	  1224	  3580 0 ));
 /* minmax inet */
 DATA(insert (	4075	869  869 1 s	  1203	  3580 0 ));
 DATA(insert (	4075	869  869 2 s	  1204	  3580 0 ));
 DATA(insert (	4075	869  869 3 s	  1201	  3580 0 ));
 DATA(insert (	4075	869  869 4 s	  1206	  3580 0 ));
 DATA(insert (	4075	869  869 5 s	  1205	  3580 0 ));
 /* inclusion inet */
 DATA(insert (	4102	869  869 3 s	  3552	  3580 0 ));
-DATA(insert (	4102	869  869 7 s	   934	  3580 0 ));
-DATA(insert (	4102	869  869 8 s	   932	  3580 0 ));
+DATA(insert (	4102	869  869 7 s	  3453	  3580 0 ));
+DATA(insert (	4102	869  869 8 s	  3451	  3580 0 ));
+DATA(insert (	4102	869  869 13 s	  3452	  3580 0 ));
+DATA(insert (	4102	869  869 14 s	  3450	  3580 0 ));
 DATA(insert (	4102	869  869 18 s	  1201	  3580 0 ));
 DATA(insert (	4102	869  869 24 s	   933	  3580 0 ));
+DATA(insert (	4102	869  869 25 s	   934	  3580 0 ));
 DATA(insert (	4102	869  869 26 s	   931	  3580 0 ));
+DATA(insert (	4102	869  869 27 s	   932	  3580 0 ));
 /* minmax character */
 DATA(insert (	4076   1042 1042 1 s	  1058	  3580 0 ));
 DATA(insert (	4076   1042 1042 2 s	  1059	  3580 0 ));
 DATA(insert (	4076   1042 1042 3 s	  1054	  3580 0 ));
 DATA(insert (	4076   1042 1042 4 s	  1061	  3580 0 ));
 DATA(insert (	4076   1042 1042 5 s	  1060	  3580 0 ));
 /* minmax time without time zone */
 DATA(insert (	4077   1083 1083 1 s	  1110	  3580 0 ));
 DATA(insert (	4077   1083 1083 2 s	  1111	  3580 0 ));
 DATA(insert (	4077   1083 1083 3 s	  1108	  3580 0 ));
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 26fa618..dc97c6e 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1141,34 +1141,46 @@ DATA(insert OID = 1202 (  "<>"	   PGNSP PGUID b f f 869 869	 16 1202 1201 networ
 DESCR("not equal");
 DATA(insert OID = 1203 (  "<"	   PGNSP PGUID b f f 869 869	 16 1205 1206 network_lt scalarltsel scalarltjoinsel ));
 DESCR("less than");
 DATA(insert OID = 1204 (  "<="	   PGNSP PGUID b f f 869 869	 16 1206 1205 network_le scalarltsel scalarltjoinsel ));
 DESCR("less than or equal");
 DATA(insert OID = 1205 (  ">"	   PGNSP PGUID b f f 869 869	 16 1203 1204 network_gt scalargtsel scalargtjoinsel ));
 DESCR("greater than");
 DATA(insert OID = 1206 (  ">="	   PGNSP PGUID b f f 869 869	 16 1204 1203 network_ge scalargtsel scalargtjoinsel ));
 DESCR("greater than or equal");
 DATA(insert OID = 931  (  "<<"	   PGNSP PGUID b f f 869 869	 16 933		0 network_sub networksel networkjoinsel ));
-DESCR("is subnet");
+DESCR("deprecated, use <<@ instead");
 #define OID_INET_SUB_OP			931
+DATA(insert OID = 3450 (  "<<@"	   PGNSP PGUID b f f 869 869	 16 3452	0 network_sub networksel networkjoinsel ));
+DESCR("is subnet");
+#define OID_INET_SUBNET_OP		3450
 DATA(insert OID = 932  (  "<<="    PGNSP PGUID b f f 869 869	 16 934		0 network_subeq networksel networkjoinsel ));
-DESCR("is subnet or equal");
+DESCR("deprecated, use <@ instead");
 #define OID_INET_SUBEQ_OP		932
+DATA(insert OID = 3451 (  "<@"	   PGNSP PGUID b f f 869 869	 16 3453	0 network_subeq networksel networkjoinsel ));
+DESCR("is contained by");
+#define OID_INET_CONTAINED_OP	3451
 DATA(insert OID = 933  (  ">>"	   PGNSP PGUID b f f 869 869	 16 931		0 network_sup networksel networkjoinsel ));
-DESCR("is supernet");
+DESCR("deprecated, use @>> instead");
 #define OID_INET_SUP_OP			933
+DATA(insert OID = 3452 (  "@>>"	   PGNSP PGUID b f f 869 869	 16 3450	0 network_sup networksel networkjoinsel ));
+DESCR("is supernet");
+#define OID_INET_SUPERNET_OP	3452
 DATA(insert OID = 934  (  ">>="    PGNSP PGUID b f f 869 869	 16 932		0 network_supeq networksel networkjoinsel ));
-DESCR("is supernet or equal");
+DESCR("deprecated, use @> instead");
 #define OID_INET_SUPEQ_OP		934
-DATA(insert OID = 3552	(  "&&"    PGNSP PGUID b f f 869 869	 16 3552	0 network_overlap networksel networkjoinsel ));
-DESCR("overlaps (is subnet or supernet)");
-#define OID_INET_OVERLAP_OP		3552
+DATA(insert OID = 3453 (  "@>"     PGNSP PGUID b f f 869 869	 16 3451	0 network_supeq networksel networkjoinsel ));
+DESCR("contains");
+#define OID_INET_CONTAINS_OP	3453
+DATA(insert OID = 3552 (  "&&"     PGNSP PGUID b f f 869 869	 16 3552	0 network_overlap networksel networkjoinsel ));
+DESCR("overlaps (contains or is contained by)");
+#define OID_INET_OVERLAPS_OP	3552
 
 DATA(insert OID = 2634 (  "~"	   PGNSP PGUID l f f	  0 869 869 0 0 inetnot - - ));
 DESCR("bitwise not");
 DATA(insert OID = 2635 (  "&"	   PGNSP PGUID b f f	869 869 869 0 0 inetand - - ));
 DESCR("bitwise and");
 DATA(insert OID = 2636 (  "|"	   PGNSP PGUID b f f	869 869 869 0 0 inetor - - ));
 DESCR("bitwise or");
 DATA(insert OID = 2637 (  "+"	   PGNSP PGUID b f f	869  20 869 2638 0 inetpl - - ));
 DESCR("add");
 DATA(insert OID = 2638 (  "+"	   PGNSP PGUID b f f	 20 869 869 2637 0 int8pl_inet - - ));
diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out
index 21676e5..9a47b57 100644
--- a/src/test/regress/expected/brin.out
+++ b/src/test/regress/expected/brin.out
@@ -173,49 +173,69 @@ INSERT INTO brinopers VALUES
 	 '{99, 100, 1, 100, 100}'),
 	('float8col', 'float8',
 	 '{>, >=, =, <=, <}',
 	 '{0, 0, 0, 1.98, 1.98}',
 	 '{99, 100, 1, 100, 100}'),
 	('macaddrcol', 'macaddr',
 	 '{>, >=, =, <=, <}',
 	 '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}',
 	 '{99, 100, 2, 100, 100}'),
 	('inetcol', 'inet',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
-	 '{100, 1, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14.231/24, 10.2/10, 10.2.14.231/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
+	('inetcol', 'inet',		-- Deprecated operators
+	 '{>>=, >>, <<=, <<}',
+	 '{10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
+	 '{2, 2, 100, 100}'),
+	('inetcol', 'inet',		-- Basic comparison operators
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{1, 100, 100, 125, 125}'),
 	('inetcol', 'inet',
-	 '{&&, >>=, <<=, =}',
+	 '{&&, @>, <@, =}',		-- IPv6
 	 '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
+	('inetcol', 'cidr',		-- Cross data-type
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14/24, 10/8, 10.2.14/25, 10.0/9}',
+	 '{100, 2, 100, 2, 100}'),
 	('inetcol', 'cidr',
-	 '{&&, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}',
-	 '{100, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{<, <=, >, >=}',
+	 '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{100, 100, 125, 125}'),
 	('inetcol', 'cidr',
-	 '{&&, >>=, <<=, =}',
+	 '{&&, @>, <@, =}',
 	 '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('cidrcol', 'inet',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
-	 '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14.231/24, 10.2.14.231/8, 10.2.14.231/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
 	('cidrcol', 'inet',
-	 '{&&, >>=, <<=, =}',
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{2, 100, 100, 125, 125}'),
+	('cidrcol', 'inet',
+	 '{&&, @>, <@, =}',
 	 '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('cidrcol', 'cidr',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}',
-	 '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14/24, 10/8, 10.2.14/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
 	('cidrcol', 'cidr',
-	 '{&&, >>=, <<=, =}',
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{2, 100, 100, 125, 125}'),
+	('cidrcol', 'cidr',
+	 '{&&, @>, <@, =}',
 	 '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('bpcharcol', 'bpchar',
 	 '{>, >=, =, <=, <}',
 	 '{A, A, W, Z, Z}',
 	 '{97, 100, 6, 100, 98}'),
 	('datecol', 'date',
 	 '{>, >=, =, <=, <}',
 	 '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}',
 	 '{100, 100, 1, 100, 100}'),
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index be9427e..74a47cf 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -172,25 +172,25 @@ SELECT '' AS six, c AS cidr, i AS inet FROM INET_TBL
   WHERE c = i;
  six |      cidr      |      inet      
 -----+----------------+----------------
      | 192.168.1.0/24 | 192.168.1.0/24
      | 10.1.2.3/32    | 10.1.2.3
 (2 rows)
 
 SELECT '' AS ten, i, c,
   i < c AS lt, i <= c AS le, i = c AS eq,
   i >= c AS ge, i > c AS gt, i <> c AS ne,
-  i << c AS sb, i <<= c AS sbe,
-  i >> c AS sup, i >>= c AS spe,
+  i <<@ c AS sb, i <@ c AS cnd,
+  i @>> c AS sup, i @> c AS cns,
   i && c AS ovr
   FROM INET_TBL;
- ten |        i         |         c          | lt | le | eq | ge | gt | ne | sb | sbe | sup | spe | ovr 
+ ten |        i         |         c          | lt | le | eq | ge | gt | ne | sb | cnd | sup | cns | ovr 
 -----+------------------+--------------------+----+----+----+----+----+----+----+-----+-----+-----+-----
      | 192.168.1.226/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t   | t
      | 192.168.1.226    | 192.168.1.0/26     | f  | f  | f  | t  | t  | t  | f  | f   | f   | f   | f
      | 192.168.1.0/24   | 192.168.1.0/24     | f  | t  | t  | t  | f  | f  | f  | t   | f   | t   | t
      | 192.168.1.0/25   | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f   | t
      | 192.168.1.255/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t   | t
      | 192.168.1.255/25 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f   | t
      | 10.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | t   | f   | t   | t
      | 10.1.2.3/8       | 10.0.0.0/32        | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
      | 10.1.2.3         | 10.1.2.3/32        | f  | t  | t  | t  | f  | f  | f  | t   | f   | t   | t
@@ -267,55 +267,87 @@ DROP INDEX inet_idx1;
 CREATE INDEX inet_idx2 ON inet_tbl using gist (i inet_ops);
 SET enable_seqscan TO off;
 SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (3 rows)
 
+SELECT * FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.255/25
+ 192.168.1.0/26 | 192.168.1.226
+(3 rows)
+
 SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (6 rows)
 
+SELECT * FROM inet_tbl WHERE i <@ '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/24
+ 192.168.1.0/24 | 192.168.1.226/24
+ 192.168.1.0/24 | 192.168.1.255/24
+ 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.255/25
+ 192.168.1.0/26 | 192.168.1.226
+(6 rows)
+
 SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (6 rows)
 
 SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
 (3 rows)
 
+SELECT * FROM inet_tbl WHERE i @> '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/24
+ 192.168.1.0/24 | 192.168.1.226/24
+ 192.168.1.0/24 | 192.168.1.255/24
+(3 rows)
+
 SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
  c | i 
 ---+---
 (0 rows)
 
+SELECT * FROM inet_tbl WHERE i @>> '192.168.1.0/24'::cidr ORDER BY i;
+ c | i 
+---+---
+(0 rows)
+
 SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i;
       c      |      i      
 -------------+-------------
  10.0.0.0/8  | 9.1.2.3/8
  10.0.0.0/32 | 10.1.2.3/8
  10.0.0.0/8  | 10.1.2.3/8
  10.0.0.0/8  | 10.1.2.3/8
  10.1.0.0/16 | 10.1.2.3/16
  10.1.2.0/24 | 10.1.2.3/24
  10.1.2.3/32 | 10.1.2.3
@@ -407,29 +439,29 @@ SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
  192.168.1.0/25
  192.168.1.255/25
  192.168.1.226
 (3 rows)
 
 SET enable_seqscan TO on;
 DROP INDEX inet_idx2;
 -- check that spgist index works correctly
 CREATE INDEX inet_idx3 ON inet_tbl using spgist (i);
 SET enable_seqscan TO off;
-SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (3 rows)
 
-SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <@ '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (6 rows)
 
@@ -437,29 +469,29 @@ SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
  192.168.1.0/24 | 192.168.1.0/25
  192.168.1.0/24 | 192.168.1.255/25
  192.168.1.0/26 | 192.168.1.226
 (6 rows)
 
-SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @> '192.168.1.0/24'::cidr ORDER BY i;
        c        |        i         
 ----------------+------------------
  192.168.1.0/24 | 192.168.1.0/24
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
 (3 rows)
 
-SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @>> '192.168.1.0/24'::cidr ORDER BY i;
  c | i 
 ---+---
 (0 rows)
 
 SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i;
       c      |      i      
 -------------+-------------
  10.0.0.0/8  | 9.1.2.3/8
  10.0.0.0/32 | 10.1.2.3/8
  10.0.0.0/8  | 10.1.2.3/8
@@ -531,32 +563,64 @@ SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i;
  192.168.1.0/24     | 192.168.1.226/24
  192.168.1.0/24     | 192.168.1.255/24
  192.168.1.0/24     | 192.168.1.0/25
  192.168.1.0/24     | 192.168.1.255/25
  192.168.1.0/26     | 192.168.1.226
  ::ffff:1.2.3.4/128 | ::4.3.2.1/24
  10:23::f1/128      | 10:23::f1/64
  10:23::8000/113    | 10:23::ffff
 (16 rows)
 
+SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.255/25
+ 192.168.1.0/26 | 192.168.1.226
+(3 rows)
+
+SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/24
+ 192.168.1.0/24 | 192.168.1.226/24
+ 192.168.1.0/24 | 192.168.1.255/24
+ 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.255/25
+ 192.168.1.0/26 | 192.168.1.226
+(6 rows)
+
+SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
+       c        |        i         
+----------------+------------------
+ 192.168.1.0/24 | 192.168.1.0/24
+ 192.168.1.0/24 | 192.168.1.226/24
+ 192.168.1.0/24 | 192.168.1.255/24
+(3 rows)
+
+SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
+ c | i 
+---+---
+(0 rows)
+
 -- test index-only scans
 EXPLAIN (COSTS OFF)
-SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
-                    QUERY PLAN                     
----------------------------------------------------
+SELECT i FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
+                     QUERY PLAN                     
+----------------------------------------------------
  Sort
    Sort Key: i
    ->  Index Only Scan using inet_idx3 on inet_tbl
-         Index Cond: (i << '192.168.1.0/24'::inet)
+         Index Cond: (i <<@ '192.168.1.0/24'::inet)
 (4 rows)
 
-SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+SELECT i FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
         i         
 ------------------
  192.168.1.0/25
  192.168.1.255/25
  192.168.1.226
 (3 rows)
 
 SET enable_seqscan TO on;
 DROP INDEX inet_idx3;
 -- simple tests of inet boolean and arithmetic operators
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 0bcec13..47b4f6b 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -953,37 +953,38 @@ ORDER BY 1, 2;
  *<   | *>
  *<=  | *>=
  *<>  | *<>
  *=   | *=
  +    | +
  -|-  | -|-
  <    | >
  <->  | <->
  <<   | >>
  <<=  | >>=
+ <<@  | @>>
  <=   | >=
  <>   | <>
  <@   | @>
  =    | =
  ?#   | ?#
  ?-   | ?-
  ?-|  | ?-|
  ?|   | ?|
  ?||  | ?||
  @    | ~
  @@   | @@
  @@@  | @@@
  |    | |
  ~<=~ | ~>=~
  ~<~  | ~>~
  ~=   | ~=
-(30 rows)
+(31 rows)
 
 -- Likewise for negator pairs.
 SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2
 FROM pg_operator o1, pg_operator o2
 WHERE o1.oprnegate = o2.oid AND o1.oprname <= o2.oprname
 ORDER BY 1, 2;
  op1  | op2  
 ------+------
  !~   | ~
  !~*  | ~*
@@ -1731,21 +1732,23 @@ ORDER BY 1, 2, 3;
         783 |            6 | -|-
         783 |            6 | ~=
         783 |            7 | @>
         783 |            8 | <@
         783 |            9 | &<|
         783 |           10 | <<|
         783 |           10 | <^
         783 |           11 | >^
         783 |           11 | |>>
         783 |           12 | |&>
+        783 |           13 | @>>
         783 |           13 | ~
+        783 |           14 | <<@
         783 |           14 | @
         783 |           15 | <->
         783 |           16 | @>
         783 |           18 | =
         783 |           19 | <>
         783 |           20 | <
         783 |           21 | <=
         783 |           22 | >
         783 |           23 | >=
         783 |           24 | <<
@@ -1769,37 +1772,39 @@ ORDER BY 1, 2, 3;
        3580 |            1 | <<
        3580 |            2 | &<
        3580 |            2 | <=
        3580 |            3 | &&
        3580 |            3 | =
        3580 |            4 | &>
        3580 |            4 | >=
        3580 |            5 | >
        3580 |            5 | >>
        3580 |            6 | ~=
-       3580 |            7 | >>=
        3580 |            7 | @>
-       3580 |            8 | <<=
        3580 |            8 | <@
        3580 |            9 | &<|
        3580 |           10 | <<|
        3580 |           11 | |>>
        3580 |           12 | |&>
+       3580 |           13 | @>>
+       3580 |           14 | <<@
        3580 |           16 | @>
        3580 |           17 | -|-
        3580 |           18 | =
        3580 |           20 | <
        3580 |           21 | <=
        3580 |           22 | >
        3580 |           23 | >=
        3580 |           24 | >>
+       3580 |           25 | >>=
        3580 |           26 | <<
+       3580 |           27 | <<=
        4000 |            1 | <<
        4000 |            1 | ~<~
        4000 |            2 | &<
        4000 |            2 | ~<=~
        4000 |            3 | &&
        4000 |            3 | =
        4000 |            4 | &>
        4000 |            4 | ~>=~
        4000 |            5 | >>
        4000 |            5 | ~>~
@@ -1808,34 +1813,36 @@ ORDER BY 1, 2, 3;
        4000 |            7 | @>
        4000 |            8 | <@
        4000 |            9 | &<|
        4000 |           10 | <<|
        4000 |           10 | <^
        4000 |           11 | <
        4000 |           11 | >^
        4000 |           11 | |>>
        4000 |           12 | <=
        4000 |           12 | |&>
+       4000 |           13 | @>>
+       4000 |           14 | <<@
        4000 |           14 | >=
        4000 |           15 | >
        4000 |           16 | @>
        4000 |           18 | =
        4000 |           19 | <>
        4000 |           20 | <
        4000 |           21 | <=
        4000 |           22 | >
        4000 |           23 | >=
        4000 |           24 | <<
        4000 |           25 | <<=
        4000 |           26 | >>
        4000 |           27 | >>=
-(121 rows)
+(127 rows)
 
 -- Check that all opclass search operators have selectivity estimators.
 -- This is not absolutely required, but it seems a reasonable thing
 -- to insist on for all standard datatypes.
 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
 FROM pg_amop AS p1, pg_operator AS p2
 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND
     (p2.oprrest = 0 OR p2.oprjoin = 0);
  amopfamily | amopopr | oid | oprname 
 ------------+---------+-----+---------
diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql
index e7f6f77..939cfdb 100644
--- a/src/test/regress/sql/brin.sql
+++ b/src/test/regress/sql/brin.sql
@@ -178,49 +178,69 @@ INSERT INTO brinopers VALUES
 	 '{99, 100, 1, 100, 100}'),
 	('float8col', 'float8',
 	 '{>, >=, =, <=, <}',
 	 '{0, 0, 0, 1.98, 1.98}',
 	 '{99, 100, 1, 100, 100}'),
 	('macaddrcol', 'macaddr',
 	 '{>, >=, =, <=, <}',
 	 '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}',
 	 '{99, 100, 2, 100, 100}'),
 	('inetcol', 'inet',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
-	 '{100, 1, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14.231/24, 10.2/10, 10.2.14.231/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
+	('inetcol', 'inet',		-- Deprecated operators
+	 '{>>=, >>, <<=, <<}',
+	 '{10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
+	 '{2, 2, 100, 100}'),
+	('inetcol', 'inet',		-- Basic comparison operators
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{1, 100, 100, 125, 125}'),
 	('inetcol', 'inet',
-	 '{&&, >>=, <<=, =}',
+	 '{&&, @>, <@, =}',		-- IPv6
 	 '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
+	('inetcol', 'cidr',		-- Cross data-type
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14/24, 10/8, 10.2.14/25, 10.0/9}',
+	 '{100, 2, 100, 2, 100}'),
 	('inetcol', 'cidr',
-	 '{&&, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}',
-	 '{100, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{<, <=, >, >=}',
+	 '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{100, 100, 125, 125}'),
 	('inetcol', 'cidr',
-	 '{&&, >>=, <<=, =}',
+	 '{&&, @>, <@, =}',
 	 '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('cidrcol', 'inet',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}',
-	 '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14.231/24, 10.2.14.231/8, 10.2.14.231/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
 	('cidrcol', 'inet',
-	 '{&&, >>=, <<=, =}',
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{2, 100, 100, 125, 125}'),
+	('cidrcol', 'inet',
+	 '{&&, @>, <@, =}',
 	 '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('cidrcol', 'cidr',
-	 '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}',
-	 '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}',
-	 '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'),
+	 '{&&, @>, <@, @>>, <<@}',
+	 '{10/8, 10.2.14/24, 10/8, 10.2.14/25, 0/0}',
+	 '{100, 2, 100, 2, 100}'),
 	('cidrcol', 'cidr',
-	 '{&&, >>=, <<=, =}',
+	 '{=, <, <=, >, >=}',
+	 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
+	 '{2, 100, 100, 125, 125}'),
+	('cidrcol', 'cidr',
+	 '{&&, @>, <@, =}',
 	 '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}',
 	 '{25, 1, 25, 1}'),
 	('bpcharcol', 'bpchar',
 	 '{>, >=, =, <=, <}',
 	 '{A, A, W, Z, Z}',
 	 '{97, 100, 6, 100, 98}'),
 	('datecol', 'date',
 	 '{>, >=, =, <=, <}',
 	 '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}',
 	 '{100, 100, 1, 100, 100}'),
diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql
index 880e115..6642d2d 100644
--- a/src/test/regress/sql/inet.sql
+++ b/src/test/regress/sql/inet.sql
@@ -44,22 +44,22 @@ SELECT '' AS ten, c AS cidr, masklen(c) AS "masklen(cidr)",
 SELECT '' AS four, c AS cidr, masklen(c) AS "masklen(cidr)",
   i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL
   WHERE masklen(c) <= 8;
 
 SELECT '' AS six, c AS cidr, i AS inet FROM INET_TBL
   WHERE c = i;
 
 SELECT '' AS ten, i, c,
   i < c AS lt, i <= c AS le, i = c AS eq,
   i >= c AS ge, i > c AS gt, i <> c AS ne,
-  i << c AS sb, i <<= c AS sbe,
-  i >> c AS sup, i >>= c AS spe,
+  i <<@ c AS sb, i <@ c AS cnd,
+  i @>> c AS sup, i @> c AS cns,
   i && c AS ovr
   FROM INET_TBL;
 
 SELECT max(i) AS max, min(i) AS min FROM INET_TBL;
 SELECT max(c) AS max, min(c) AS min FROM INET_TBL;
 
 -- check the conversion to/from text and set_netmask
 SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
 
 -- check that btree index works correctly
@@ -67,58 +67,66 @@ CREATE INDEX inet_idx1 ON inet_tbl(i);
 SET enable_seqscan TO off;
 SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr;
 SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr;
 SET enable_seqscan TO on;
 DROP INDEX inet_idx1;
 
 -- check that gist index works correctly
 CREATE INDEX inet_idx2 ON inet_tbl using gist (i inet_ops);
 SET enable_seqscan TO off;
 SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <@ '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @> '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @>> '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i;
 
 -- test index-only scans
 EXPLAIN (COSTS OFF)
 SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
 SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
 
 SET enable_seqscan TO on;
 DROP INDEX inet_idx2;
 
 -- check that spgist index works correctly
 CREATE INDEX inet_idx3 ON inet_tbl using spgist (i);
 SET enable_seqscan TO off;
-SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
-SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <@ '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i;
-SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
-SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @> '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i @>> '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i;
 SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i;
+SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i;
 
 -- test index-only scans
 EXPLAIN (COSTS OFF)
-SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
-SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i;
+SELECT i FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
+SELECT i FROM inet_tbl WHERE i <<@ '192.168.1.0/24'::cidr ORDER BY i;
 
 SET enable_seqscan TO on;
 DROP INDEX inet_idx3;
 
 -- simple tests of inet boolean and arithmetic operators
 SELECT i, ~i AS "~i" FROM inet_tbl;
 SELECT i, c, i & c AS "and" FROM inet_tbl;
 SELECT i, c, i | c AS "or" FROM inet_tbl;
 SELECT i, i + 500 AS "i+500" FROM inet_tbl;
 SELECT i, i - 500 AS "i-500" FROM inet_tbl;
-- 
2.9.3 (Apple Git-75)

