diff -urdN postgresql-13.0-orig/doc/src/sgml/func.sgml postgresql-13.0-range-ext/doc/src/sgml/func.sgml
--- postgresql-13.0-orig/doc/src/sgml/func.sgml	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/doc/src/sgml/func.sgml	2020-09-27 14:13:51.621421300 +0200
@@ -18024,6 +18024,34 @@
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
+        <type>anyrange</type> <literal>&lt;&lt;</literal> <type>anyelement</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the range strictly left of the element?
+       </para>
+       <para>
+        <literal>int8range(1,10) &lt;&lt; 100::int8</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyelement</type> <literal>&lt;&lt;</literal> <type>anyrange</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the element strictly left of the range?
+       </para>
+       <para>
+        <literal>10::int8 &lt;&lt; int8range(100,110)</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
         <type>anyrange</type> <literal>&gt;&gt;</literal> <type>anyrange</type>
         <returnvalue>boolean</returnvalue>
        </para>
@@ -18038,6 +18066,34 @@
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
+        <type>anyrange</type> <literal>&gt;&gt;</literal> <type>anyelement</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the range strictly right of the element?
+       </para>
+       <para>
+        <literal>int8range(50,60) &gt;&gt; 20::int8</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyelement</type> <literal>&gt;&gt;</literal> <type>anyrange</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the element strictly right of the element?
+       </para>
+       <para>
+        <literal>60::int8 &gt;&gt; int8range(20,30)</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
         <type>anyrange</type> <literal>&amp;&lt;</literal> <type>anyrange</type>
         <returnvalue>boolean</returnvalue>
        </para>
@@ -18052,6 +18108,34 @@
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
+        <type>anyrange</type> <literal>&amp;&lt;</literal> <type>anyelement</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Does the range not extend to the right of the element?
+       </para>
+       <para>
+        <literal>int8range(1,20) &amp;&lt; 20::int8</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyelement</type> <literal>&amp;&lt;</literal> <type>anyrange</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Does the element not extend to the right of the range?
+       </para>
+       <para>
+        <literal>20::int8 &amp;&lt; int8range(18,20)</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
         <type>anyrange</type> <literal>&amp;&gt;</literal> <type>anyrange</type>
         <returnvalue>boolean</returnvalue>
        </para>
@@ -18066,6 +18150,34 @@
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
+        <type>anyrange</type> <literal>&amp;&gt;</literal> <type>anyelement</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Does the range not extend to the left of the element?
+       </para>
+       <para>
+        <literal>int8range(7,20) &amp;&gt; 5::int8</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyelement</type> <literal>&amp;&gt;</literal> <type>anyrange</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Does the element not extend to the left of the range?
+       </para>
+       <para>
+        <literal>7::int8 &amp;&gt; int8range(5,10)</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
         <type>anyrange</type> <literal>-|-</literal> <type>anyrange</type>
         <returnvalue>boolean</returnvalue>
        </para>
@@ -18077,6 +18189,34 @@
         <returnvalue>t</returnvalue>
        </para></entry>
       </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyrange</type> <literal>-|-</literal> <type>anyelement</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the range adjacent to the element?
+       </para>
+       <para>
+        <literal>numrange(1.1,2.2) -|- 2.2</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <type>anyelement</type> <literal>-|-</literal> <type>anyrange</type>
+        <returnvalue>boolean</returnvalue>
+       </para>
+       <para>
+        Is the element adjacent to the range?
+       </para>
+       <para>
+        <literal>2.2 -|- numrange(2.2,3.3,'(]')</literal>
+        <returnvalue>t</returnvalue>
+       </para></entry>
+      </row>
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
diff -urdN postgresql-13.0-orig/src/backend/utils/adt/rangetypes.c postgresql-13.0-range-ext/src/backend/utils/adt/rangetypes.c
--- postgresql-13.0-orig/src/backend/utils/adt/rangetypes.c	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/backend/utils/adt/rangetypes.c	2020-09-27 12:39:35.221421300 +0200
@@ -536,6 +536,323 @@
 	PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
 }
 
+/* strictly left of element? (internal version) */
+bool
+range_before_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+	int32		cmp;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any other range */
+	if (empty)
+		return false;
+
+	if (!upper.infinite)
+	{
+		cmp = DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											  typcache->rng_collation,
+											  upper.val, val));
+		if (cmp < 0 ||
+			(cmp == 0 && !upper.inclusive))
+			return true;
+	}
+
+	return false;
+}
+
+/* strictly left of element? */
+Datum
+range_before_elem(PG_FUNCTION_ARGS)
+{
+	RangeType  *r = PG_GETARG_RANGE_P(0);
+	Datum		val = PG_GETARG_DATUM(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_before_elem_internal(typcache, r, val));
+}
+
+/* does not extend to right of element? (internal version) */
+bool
+range_overleft_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any element */
+	if (empty)
+		return false;
+
+	if (!upper.infinite)
+	{
+		if (DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											typcache->rng_collation,
+											upper.val, val)) <= 0)
+			return true;
+	}
+
+	return false;
+}
+
+/* does not extend to right of element? */
+Datum
+range_overleft_elem(PG_FUNCTION_ARGS)
+{
+	RangeType  *r = PG_GETARG_RANGE_P(0);
+	Datum		val = PG_GETARG_DATUM(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_overleft_elem_internal(typcache, r, val));
+}
+
+/* strictly right of element? (internal version) */
+bool
+range_after_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+	int32		cmp;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any other range */
+	if (empty)
+		return false;
+
+	if (!lower.infinite)
+	{
+		cmp = DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											  typcache->rng_collation,
+											  lower.val, val));
+		if (cmp > 0 ||
+			(cmp == 0 && !lower.inclusive))
+			return true;
+	}
+
+	return false;
+}
+
+/* strictly right of element? */
+Datum
+range_after_elem(PG_FUNCTION_ARGS)
+{
+	RangeType  *r = PG_GETARG_RANGE_P(0);
+	Datum		val = PG_GETARG_DATUM(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_after_elem_internal(typcache, r, val));
+}
+
+/* does not extend to left of element? (internal version) */
+bool
+range_overright_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any element */
+	if (empty)
+		return false;
+
+	if (!lower.infinite)
+	{
+		if (DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											typcache->rng_collation,
+											lower.val, val)) >= 0)
+			return true;
+	}
+
+	return false;
+}
+
+/* does not extend to left of element? */
+Datum
+range_overright_elem(PG_FUNCTION_ARGS)
+{
+	RangeType  *r = PG_GETARG_RANGE_P(0);
+	Datum		val = PG_GETARG_DATUM(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_overright_elem_internal(typcache, r, val));
+}
+
+/* adjacent to element (but not overlapping)? (internal version) */
+bool
+range_adjacent_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+	RangeBound 	elembound;
+	bool		isadj;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is not adjacent to any element */
+	if (empty)
+		return false;
+
+	/*
+	 * A range A..B and a value V are adjacent if and only if
+	 * B is adjacent to V, or V is adjacent to A.
+	 */
+	elembound.val = val;
+	elembound.infinite = false;
+	elembound.inclusive = true;
+	elembound.lower = true;
+	isadj = bounds_adjacent(typcache, upper, elembound);
+	elembound.lower = false;
+	return (isadj || bounds_adjacent(typcache, elembound, lower));
+}
+
+/* adjacent to element (but not overlapping)? */
+Datum
+range_adjacent_elem(PG_FUNCTION_ARGS)
+{
+	RangeType  *r = PG_GETARG_RANGE_P(0);
+	Datum		val = PG_GETARG_DATUM(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_adjacent_elem_internal(typcache, r, val));
+}
+
+/******************************************************************************/
+
+/* element strictly left of? */
+Datum
+elem_before_range(PG_FUNCTION_ARGS)
+{
+	Datum		val = PG_GETARG_DATUM(0);
+	RangeType  *r = PG_GETARG_RANGE_P(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_after_elem_internal(typcache, r, val));
+}
+
+/* element does not extend to right of? (internal version) */
+bool
+elem_overleft_range_internal(TypeCacheEntry *typcache, Datum val, RangeType *r)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any element */
+	if (empty)
+		return false;
+
+	if (!upper.infinite)
+	{
+		if (DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											typcache->rng_collation,
+											val, upper.val)) <= 0)
+			return true;
+	}
+
+	return false;
+}
+
+/* element does not extend to right of? */
+Datum
+elem_overleft_range(PG_FUNCTION_ARGS)
+{
+	Datum		val = PG_GETARG_DATUM(0);
+	RangeType  *r = PG_GETARG_RANGE_P(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(elem_overleft_range_internal(typcache, val, r));
+}
+
+/* element strictly right of? */
+Datum
+elem_after_range(PG_FUNCTION_ARGS)
+{
+	Datum		val = PG_GETARG_DATUM(0);
+	RangeType  *r = PG_GETARG_RANGE_P(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_before_elem_internal(typcache, r, val));
+}
+
+/* element does not extend to left of? (internal version) */
+bool
+elem_overright_range_internal(TypeCacheEntry *typcache, Datum val, RangeType *r)
+{
+	RangeBound	lower,
+				upper;
+	bool		empty;
+
+	range_deserialize(typcache, r, &lower, &upper, &empty);
+
+	/* An empty range is neither left nor right any element */
+	if (empty)
+		return false;
+
+	if (!lower.infinite)
+	{
+		if (DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
+											typcache->rng_collation,
+											val, lower.val)) >= 0)
+			return true;
+	}
+
+	return false;
+}
+
+/* element does not extend the left of? */
+Datum
+elem_overright_range(PG_FUNCTION_ARGS)
+{
+	Datum		val = PG_GETARG_DATUM(0);
+	RangeType  *r = PG_GETARG_RANGE_P(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(elem_overright_range_internal(typcache, val, r));
+}
+
+/* element adjacent to? */
+Datum
+elem_adjacent_range(PG_FUNCTION_ARGS)
+{
+	Datum		val = PG_GETARG_DATUM(0);
+	RangeType  *r = PG_GETARG_RANGE_P(1);
+	TypeCacheEntry *typcache;
+
+	typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
+
+	PG_RETURN_BOOL(range_adjacent_elem_internal(typcache, r, val));
+}
+
 /* contained by? */
 Datum
 elem_contained_by_range(PG_FUNCTION_ARGS)
@@ -549,7 +866,6 @@
 	PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
 }
 
-
 /* range, range -> bool functions */
 
 /* equality (internal version) */
diff -urdN postgresql-13.0-orig/src/include/catalog/pg_operator.dat postgresql-13.0-range-ext/src/include/catalog/pg_operator.dat
--- postgresql-13.0-orig/src/include/catalog/pg_operator.dat	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/include/catalog/pg_operator.dat	2020-09-27 13:01:08.681421300 +0200
@@ -3327,5 +3327,59 @@
   oprname => '@@', oprleft => 'jsonb', oprright => 'jsonpath',
   oprresult => 'bool', oprcode => 'jsonb_path_match_opr(jsonb,jsonpath)',
   oprrest => 'matchingsel', oprjoin => 'matchingjoinsel' },
+{ oid => '4231', oid_symbol => 'OID_RANGE_ADJACENT_ELEM_OP',
+  descr => 'range is adjacent to element',
+  oprname => '-|-', oprleft => 'anyrange', oprright => 'anyelement',
+  oprresult => 'bool', oprcom => '-|-(anyelement,anyrange)',
+  oprcode => 'range_adjacent_elem', oprrest => 'contsel', oprjoin => 'contjoinsel' },
+{ oid => '4232', oid_symbol => 'OID_ELEM_ADJACENT_RANGE_OP',
+  descr => 'element is adjacent to range',
+  oprname => '-|-', oprleft => 'anyelement', oprright => 'anyrange',
+  oprresult => 'bool', oprcom => '-|-(anyrange,anyelement)',
+  oprcode => 'elem_adjacent_range', oprrest => 'contsel', oprjoin => 'contjoinsel' },
+{ oid => '4233', oid_symbol => 'OID_RANGE_LEFT_ELEM_OP',
+  descr => 'is left of element',
+  oprname => '<<', oprleft => 'anyrange', oprright => 'anyelement',
+  oprresult => 'bool', oprcom => '>>(anyelement,anyrange)',
+  oprcode => 'range_before_elem', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '4234', oid_symbol => 'OID_ELEM_LEFT_RANGE_OP',
+  descr => 'element is left of range',
+  oprname => '<<', oprleft => 'anyelement', oprright => 'anyrange',
+  oprresult => 'bool', oprcom => '>>(anyrange,anyelement)',
+  oprcode => 'elem_before_range', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '4235', oid_symbol => 'OID_RANGE_RIGHT_ELEM_OP',
+  descr => 'is right of element',
+  oprname => '>>', oprleft => 'anyrange', oprright => 'anyelement',
+  oprresult => 'bool', oprcom => '<<(anyelement,anyrange)',
+  oprcode => 'range_after_elem', oprrest => 'rangesel',
+  oprjoin => 'scalargtjoinsel' },
+{ oid => '4236', oid_symbol => 'OID_ELEM_RIGHT_RANGE_OP',
+  descr => 'element is right of range',
+  oprname => '>>', oprleft => 'anyelement', oprright => 'anyrange',
+  oprresult => 'bool', oprcom => '<<(anyrange,anyelement)',
+  oprcode => 'elem_after_range', oprrest => 'rangesel',
+  oprjoin => 'scalargtjoinsel' },
+{ oid => '4237', oid_symbol => 'OID_RANGE_OVERLAPS_LEFT_ELEM_OP',
+  descr => 'overlaps or is left of element',
+  oprname => '&<', oprleft => 'anyrange', oprright => 'anyelement',
+  oprresult => 'bool', oprcode => 'range_overleft_elem', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '4238', oid_symbol => 'OID_ELEM_OVERLAPS_LEFT_RANGE_OP',
+  descr => 'element overlaps or is left of range',
+  oprname => '&<', oprleft => 'anyelement', oprright => 'anyrange',
+  oprresult => 'bool', oprcode => 'elem_overleft_range', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '4239', oid_symbol => 'OID_RANGE_OVERLAPS_RIGHT_ELEM_OP',
+  descr => 'overlaps or is right of element',
+  oprname => '&>', oprleft => 'anyrange', oprright => 'anyelement',
+  oprresult => 'bool', oprcode => 'range_overright_elem', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '4240', oid_symbol => 'OID_ELEM_OVERLAPS_RIGHT_RANGE_OP',
+  descr => 'element overlaps or is right of range',
+  oprname => '&>', oprleft => 'anyelement', oprright => 'anyrange',
+  oprresult => 'bool', oprcode => 'elem_overright_range', oprrest => 'rangesel',
+  oprjoin => 'scalarltjoinsel' },
 
 ]
diff -urdN postgresql-13.0-orig/src/include/catalog/pg_proc.dat postgresql-13.0-range-ext/src/include/catalog/pg_proc.dat
--- postgresql-13.0-orig/src/include/catalog/pg_proc.dat	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/include/catalog/pg_proc.dat	2020-09-27 13:31:54.351421300 +0200
@@ -9913,6 +9913,37 @@
   proname => 'int8range', proisstrict => 'f', prorettype => 'int8range',
   proargtypes => 'int8 int8 text', prosrc => 'range_constructor3' },
 
+{ oid => '4241',
+  proname => 'range_adjacent_elem', prorettype => 'bool',
+  proargtypes => 'anyrange anyelement', prosrc => 'range_adjacent_elem' },
+{ oid => '4242',
+  proname => 'elem_adjacent_range', prorettype => 'bool',
+  proargtypes => 'anyelement anyrange', prosrc => 'elem_adjacent_range' },
+{ oid => '4243',
+  proname => 'range_before_elem', prorettype => 'bool',
+  proargtypes => 'anyrange anyelement', prosrc => 'range_before_elem' },
+{ oid => '4244',
+  proname => 'elem_before_range', prorettype => 'bool',
+  proargtypes => 'anyelement anyrange', prosrc => 'elem_before_range' },
+{ oid => '4245',
+  proname => 'range_after_elem', prorettype => 'bool',
+  proargtypes => 'anyrange anyelement', prosrc => 'range_after_elem' },
+{ oid => '4246',
+  proname => 'elem_after_range', prorettype => 'bool',
+  proargtypes => 'anyelement anyrange', prosrc => 'elem_after_range' },
+{ oid => '4247',
+  proname => 'range_overleft_elem', prorettype => 'bool',
+  proargtypes => 'anyrange anyelement', prosrc => 'range_overleft_elem' },
+{ oid => '4248',
+  proname => 'elem_overleft_range', prorettype => 'bool',
+  proargtypes => 'anyelement anyrange', prosrc => 'elem_overleft_range' },
+{ oid => '4249',
+  proname => 'range_overright_elem', prorettype => 'bool',
+  proargtypes => 'anyrange anyelement', prosrc => 'range_overright_elem' },
+{ oid => '4250',
+  proname => 'elem_overright_range', prorettype => 'bool',
+  proargtypes => 'anyelement anyrange', prosrc => 'elem_overright_range' },
+
 # date, time, timestamp constructors
 { oid => '3846', descr => 'construct date',
   proname => 'make_date', prorettype => 'date', proargtypes => 'int4 int4 int4',
diff -urdN postgresql-13.0-orig/src/include/utils/rangetypes.h postgresql-13.0-range-ext/src/include/utils/rangetypes.h
--- postgresql-13.0-orig/src/include/utils/rangetypes.h	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/include/utils/rangetypes.h	2020-09-27 12:36:10.811421300 +0200
@@ -93,6 +93,13 @@
  */
 
 extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val);
+extern bool range_before_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool range_overleft_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool range_after_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool range_overright_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool range_adjacent_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool elem_overleft_range_internal(TypeCacheEntry *typcache, Datum val, RangeType *r);
+extern bool elem_overright_range_internal(TypeCacheEntry *typcache, Datum val, RangeType *r);
 
 /* internal versions of the above */
 extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1,
diff -urdN postgresql-13.0-orig/src/test/regress/expected/rangetypes.out postgresql-13.0-range-ext/src/test/regress/expected/rangetypes.out
--- postgresql-13.0-orig/src/test/regress/expected/rangetypes.out	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/test/regress/expected/rangetypes.out	2020-09-27 15:28:52.221421300 +0200
@@ -372,6 +372,18 @@
  t
 (1 row)
 
+select numrange(1.0, 2.0) -|- 2.0;
+ ?column? 
+----------
+ t
+(1 row)
+
+select 2.0 -|- numrange(2.0, 3.0,'()');
+ ?column? 
+----------
+ t
+(1 row)
+
 select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
  range_adjacent 
 ----------------
@@ -432,6 +444,18 @@
  t
 (1 row)
 
+select numrange(1.0, 2.0) << 3.0;
+ ?column? 
+----------
+ t
+(1 row)
+
+select 2.0 << numrange(3.0, 4.0);
+ ?column? 
+----------
+ t
+(1 row)
+
 select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
  ?column? 
 ----------
@@ -450,12 +474,54 @@
  f
 (1 row)
 
+select numrange(1.0, 2.0) >> 3.0;
+ ?column? 
+----------
+ f
+(1 row)
+
+select 2.0 >> numrange(3.0, 4.0);
+ ?column? 
+----------
+ f
+(1 row)
+
 select numrange(3.0, 70.0) &< numrange(6.6, 100.0);
  ?column? 
 ----------
  t
 (1 row)
 
+select numrange(3.0, 70.0) &< 6.6;
+ ?column? 
+----------
+ f
+(1 row)
+
+select 70.0 &< numrange(6.6, 100.0);
+ ?column? 
+----------
+ t
+(1 row)
+
+select numrange(3.0, 70.0) &> numrange(6.6, 100.0);
+ ?column? 
+----------
+ f
+(1 row)
+
+select numrange(3.0, 70.0) &> 6.6;
+ ?column? 
+----------
+ f
+(1 row)
+
+select 70.0 &> numrange(6.6, 100.0);
+ ?column? 
+----------
+ t
+(1 row)
+
 select numrange(1.1, 2.2) < numrange(1.0, 200.2);
  ?column? 
 ----------
@@ -819,30 +885,60 @@
    189
 (1 row)
 
+select count(*) from test_range_gist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_gist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_gist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_gist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_gist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_gist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_gist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- now check same queries using index
 SET enable_seqscan    = f;
 SET enable_indexscan  = t;
@@ -889,30 +985,60 @@
    189
 (1 row)
 
+select count(*) from test_range_gist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_gist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_gist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_gist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_gist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_gist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_gist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- now check same queries using a bulk-loaded index
 drop index test_range_gist_idx;
 create index test_range_gist_idx on test_range_gist using gist (ir);
@@ -958,30 +1084,60 @@
    189
 (1 row)
 
+select count(*) from test_range_gist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_gist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_gist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_gist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_gist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_gist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_gist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_gist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- test SP-GiST index that's been built incrementally
 create table test_range_spgist(ir int4range);
 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
@@ -1038,30 +1194,60 @@
    189
 (1 row)
 
+select count(*) from test_range_spgist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_spgist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_spgist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_spgist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_spgist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_spgist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- now check same queries using index
 SET enable_seqscan    = f;
 SET enable_indexscan  = t;
@@ -1108,30 +1294,60 @@
    189
 (1 row)
 
+select count(*) from test_range_spgist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_spgist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_spgist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_spgist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_spgist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_spgist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- now check same queries using a bulk-loaded index
 drop index test_range_spgist_idx;
 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
@@ -1177,30 +1393,60 @@
    189
 (1 row)
 
+select count(*) from test_range_spgist where ir << 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir >> int4range(100,500);
  count 
 -------
   3554
 (1 row)
 
+select count(*) from test_range_spgist where ir >> 100;
+ count 
+-------
+  4791
+(1 row)
+
 select count(*) from test_range_spgist where ir &< int4range(100,500);
  count 
 -------
   1029
 (1 row)
 
+select count(*) from test_range_spgist where ir &< 100;
+ count 
+-------
+   189
+(1 row)
+
 select count(*) from test_range_spgist where ir &> int4range(100,500);
  count 
 -------
   4794
 (1 row)
 
+select count(*) from test_range_spgist where ir &> 100;
+ count 
+-------
+  4794
+(1 row)
+
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
  count 
 -------
      5
 (1 row)
 
+select count(*) from test_range_spgist where ir -|- 100;
+ count 
+-------
+     6
+(1 row)
+
 -- test index-only scans
 explain (costs off)
 select ir from test_range_spgist where ir -|- int4range(10,20) order by ir;
diff -urdN postgresql-13.0-orig/src/test/regress/sql/rangetypes.sql postgresql-13.0-range-ext/src/test/regress/sql/rangetypes.sql
--- postgresql-13.0-orig/src/test/regress/sql/rangetypes.sql	2020-09-21 22:47:36.000000000 +0200
+++ postgresql-13.0-range-ext/src/test/regress/sql/rangetypes.sql	2020-09-27 15:28:52.231421300 +0200
@@ -87,6 +87,9 @@
 select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]');
 select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
 
+select numrange(1.0, 2.0) -|- 2.0;
+select 2.0 -|- numrange(2.0, 3.0,'()');
+
 select numrange(1.1, 3.3) <@ numrange(0.1,10.1);
 select numrange(0.1, 10.1) <@ numrange(1.1,3.3);
 
@@ -98,10 +101,19 @@
 
 select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5);
 select numrange(1.0, 2.0) << numrange(3.0, 4.0);
+select numrange(1.0, 2.0) << 3.0;
+select 2.0 << numrange(3.0, 4.0);
 select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
 select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()');
 select numrange(1.0, 2.0) >> numrange(3.0, 4.0);
+select numrange(1.0, 2.0) >> 3.0;
+select 2.0 >> numrange(3.0, 4.0);
 select numrange(3.0, 70.0) &< numrange(6.6, 100.0);
+select numrange(3.0, 70.0) &< 6.6;
+select 70.0 &< numrange(6.6, 100.0);
+select numrange(3.0, 70.0) &> numrange(6.6, 100.0);
+select numrange(3.0, 70.0) &> 6.6;
+select 70.0 &> numrange(6.6, 100.0);
 
 select numrange(1.1, 2.2) < numrange(1.0, 200.2);
 select numrange(1.1, 2.2) < numrange(1.1, 1.2);
@@ -222,10 +234,15 @@
 select count(*) from test_range_gist where ir && int4range(10,20);
 select count(*) from test_range_gist where ir <@ int4range(10,50);
 select count(*) from test_range_gist where ir << int4range(100,500);
+select count(*) from test_range_gist where ir << 100;
 select count(*) from test_range_gist where ir >> int4range(100,500);
+select count(*) from test_range_gist where ir >> 100;
 select count(*) from test_range_gist where ir &< int4range(100,500);
+select count(*) from test_range_gist where ir &< 100;
 select count(*) from test_range_gist where ir &> int4range(100,500);
+select count(*) from test_range_gist where ir &> 100;
 select count(*) from test_range_gist where ir -|- int4range(100,500);
+select count(*) from test_range_gist where ir -|- 100;
 
 -- now check same queries using index
 SET enable_seqscan    = f;
@@ -239,10 +256,15 @@
 select count(*) from test_range_gist where ir && int4range(10,20);
 select count(*) from test_range_gist where ir <@ int4range(10,50);
 select count(*) from test_range_gist where ir << int4range(100,500);
+select count(*) from test_range_gist where ir << 100;
 select count(*) from test_range_gist where ir >> int4range(100,500);
+select count(*) from test_range_gist where ir >> 100;
 select count(*) from test_range_gist where ir &< int4range(100,500);
+select count(*) from test_range_gist where ir &< 100;
 select count(*) from test_range_gist where ir &> int4range(100,500);
+select count(*) from test_range_gist where ir &> 100;
 select count(*) from test_range_gist where ir -|- int4range(100,500);
+select count(*) from test_range_gist where ir -|- 100;
 
 -- now check same queries using a bulk-loaded index
 drop index test_range_gist_idx;
@@ -255,10 +277,15 @@
 select count(*) from test_range_gist where ir && int4range(10,20);
 select count(*) from test_range_gist where ir <@ int4range(10,50);
 select count(*) from test_range_gist where ir << int4range(100,500);
+select count(*) from test_range_gist where ir << 100;
 select count(*) from test_range_gist where ir >> int4range(100,500);
+select count(*) from test_range_gist where ir >> 100;
 select count(*) from test_range_gist where ir &< int4range(100,500);
+select count(*) from test_range_gist where ir &< 100;
 select count(*) from test_range_gist where ir &> int4range(100,500);
+select count(*) from test_range_gist where ir &> 100;
 select count(*) from test_range_gist where ir -|- int4range(100,500);
+select count(*) from test_range_gist where ir -|- 100;
 
 -- test SP-GiST index that's been built incrementally
 create table test_range_spgist(ir int4range);
@@ -284,10 +311,15 @@
 select count(*) from test_range_spgist where ir && int4range(10,20);
 select count(*) from test_range_spgist where ir <@ int4range(10,50);
 select count(*) from test_range_spgist where ir << int4range(100,500);
+select count(*) from test_range_spgist where ir << 100;
 select count(*) from test_range_spgist where ir >> int4range(100,500);
+select count(*) from test_range_spgist where ir >> 100;
 select count(*) from test_range_spgist where ir &< int4range(100,500);
+select count(*) from test_range_spgist where ir &< 100;
 select count(*) from test_range_spgist where ir &> int4range(100,500);
+select count(*) from test_range_spgist where ir &> 100;
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
+select count(*) from test_range_spgist where ir -|- 100;
 
 -- now check same queries using index
 SET enable_seqscan    = f;
@@ -301,10 +333,15 @@
 select count(*) from test_range_spgist where ir && int4range(10,20);
 select count(*) from test_range_spgist where ir <@ int4range(10,50);
 select count(*) from test_range_spgist where ir << int4range(100,500);
+select count(*) from test_range_spgist where ir << 100;
 select count(*) from test_range_spgist where ir >> int4range(100,500);
+select count(*) from test_range_spgist where ir >> 100;
 select count(*) from test_range_spgist where ir &< int4range(100,500);
+select count(*) from test_range_spgist where ir &< 100;
 select count(*) from test_range_spgist where ir &> int4range(100,500);
+select count(*) from test_range_spgist where ir &> 100;
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
+select count(*) from test_range_spgist where ir -|- 100;
 
 -- now check same queries using a bulk-loaded index
 drop index test_range_spgist_idx;
@@ -317,10 +354,15 @@
 select count(*) from test_range_spgist where ir && int4range(10,20);
 select count(*) from test_range_spgist where ir <@ int4range(10,50);
 select count(*) from test_range_spgist where ir << int4range(100,500);
+select count(*) from test_range_spgist where ir << 100;
 select count(*) from test_range_spgist where ir >> int4range(100,500);
+select count(*) from test_range_spgist where ir >> 100;
 select count(*) from test_range_spgist where ir &< int4range(100,500);
+select count(*) from test_range_spgist where ir &< 100;
 select count(*) from test_range_spgist where ir &> int4range(100,500);
+select count(*) from test_range_spgist where ir &> 100;
 select count(*) from test_range_spgist where ir -|- int4range(100,500);
+select count(*) from test_range_spgist where ir -|- 100;
 
 -- test index-only scans
 explain (costs off)
