diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml
index 1998171..9203497 100644
--- a/doc/src/sgml/indices.sgml
+++ b/doc/src/sgml/indices.sgml
@@ -183,6 +183,24 @@ SELECT * FROM events ORDER BY event_date <-> date '2017-05-05' LIMIT 10;
which finds the ten events closest to a given target date. The ability
to do this is again dependent on the particular operator class being used.
+ Built-in B-tree operator classes support distance ordering for the following
+ data types:
+
+ int2
+ int4
+ int8
+ float4
+ float8
+ numeric
+ timestamp with time zone
+ timestamp without time zone
+ time with time zone
+ time without time zone
+ date
+ interval
+ oid
+ money
+
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index c92e9d5..83073c4 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -30,6 +30,7 @@
#include "utils/numeric.h"
#include "utils/pg_locale.h"
+#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
/*************************************************************************
* Private routines
@@ -1157,3 +1158,22 @@ int8_cash(PG_FUNCTION_ARGS)
PG_RETURN_CASH(result);
}
+
+Datum
+cash_distance(PG_FUNCTION_ARGS)
+{
+ Cash a = PG_GETARG_CASH(0);
+ Cash b = PG_GETARG_CASH(1);
+ Cash r;
+ Cash ra;
+
+ if (pg_sub_s64_overflow(a, b, &r) ||
+ r == PG_INT64_MIN)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("money out of range")));
+
+ ra = Abs(r);
+
+ PG_RETURN_CASH(ra);
+}
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index cf5a1c6..4492f69 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -563,6 +563,17 @@ date_mii(PG_FUNCTION_ARGS)
PG_RETURN_DATEADT(result);
}
+Datum
+date_distance(PG_FUNCTION_ARGS)
+{
+ /* we assume the difference can't overflow */
+ Datum diff = DirectFunctionCall2(date_mi,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1));
+
+ PG_RETURN_INT32(Abs(DatumGetInt32(diff)));
+}
+
/*
* Internal routines for promoting date to timestamp and timestamp with
* time zone
@@ -760,6 +771,29 @@ date_cmp_timestamp(PG_FUNCTION_ARGS)
}
Datum
+date_dist_timestamp(PG_FUNCTION_ARGS)
+{
+ DateADT dateVal = PG_GETARG_DATEADT(0);
+ Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
+ Timestamp dt1;
+
+ if (DATE_NOT_FINITE(dateVal) || TIMESTAMP_NOT_FINITE(dt2))
+ {
+ Interval *r = palloc(sizeof(Interval));
+
+ r->day = INT_MAX;
+ r->month = INT_MAX;
+ r->time = PG_INT64_MAX;
+
+ PG_RETURN_INTERVAL_P(r);
+ }
+
+ dt1 = date2timestamp(dateVal);
+
+ PG_RETURN_INTERVAL_P(timestamp_dist_internal(dt1, dt2));
+}
+
+Datum
date_eq_timestamptz(PG_FUNCTION_ARGS)
{
DateADT dateVal = PG_GETARG_DATEADT(0);
@@ -844,6 +878,30 @@ date_cmp_timestamptz(PG_FUNCTION_ARGS)
}
Datum
+date_dist_timestamptz(PG_FUNCTION_ARGS)
+{
+ DateADT dateVal = PG_GETARG_DATEADT(0);
+ TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
+ TimestampTz dt1;
+
+ if (DATE_NOT_FINITE(dateVal) || TIMESTAMP_NOT_FINITE(dt2))
+ {
+ Interval *r = palloc(sizeof(Interval));
+
+ r->day = INT_MAX;
+ r->month = INT_MAX;
+ r->time = PG_INT64_MAX;
+
+ PG_RETURN_INTERVAL_P(r);
+ }
+
+ dt1 = date2timestamptz(dateVal);
+
+ PG_RETURN_INTERVAL_P(timestamptz_dist_internal(dt1, dt2));
+}
+
+
+Datum
timestamp_eq_date(PG_FUNCTION_ARGS)
{
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
@@ -928,6 +986,29 @@ timestamp_cmp_date(PG_FUNCTION_ARGS)
}
Datum
+timestamp_dist_date(PG_FUNCTION_ARGS)
+{
+ Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
+ DateADT dateVal = PG_GETARG_DATEADT(1);
+ Timestamp dt2;
+
+ if (DATE_NOT_FINITE(dateVal) || TIMESTAMP_NOT_FINITE(dt1))
+ {
+ Interval *r = palloc(sizeof(Interval));
+
+ r->day = INT_MAX;
+ r->month = INT_MAX;
+ r->time = PG_INT64_MAX;
+
+ PG_RETURN_INTERVAL_P(r);
+ }
+
+ dt2 = date2timestamp(dateVal);
+
+ PG_RETURN_INTERVAL_P(timestamp_dist_internal(dt1, dt2));
+}
+
+Datum
timestamptz_eq_date(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
@@ -1039,6 +1120,28 @@ in_range_date_interval(PG_FUNCTION_ARGS)
BoolGetDatum(less));
}
+Datum
+timestamptz_dist_date(PG_FUNCTION_ARGS)
+{
+ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
+ DateADT dateVal = PG_GETARG_DATEADT(1);
+ TimestampTz dt2;
+
+ if (DATE_NOT_FINITE(dateVal) || TIMESTAMP_NOT_FINITE(dt1))
+ {
+ Interval *r = palloc(sizeof(Interval));
+
+ r->day = INT_MAX;
+ r->month = INT_MAX;
+ r->time = PG_INT64_MAX;
+
+ PG_RETURN_INTERVAL_P(r);
+ }
+
+ dt2 = date2timestamptz(dateVal);
+
+ PG_RETURN_INTERVAL_P(timestamptz_dist_internal(dt1, dt2));
+}
/* Add an interval to a date, giving a new date.
* Must handle both positive and negative intervals.
@@ -1957,6 +2060,16 @@ time_part(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(result);
}
+Datum
+time_distance(PG_FUNCTION_ARGS)
+{
+ Datum diff = DirectFunctionCall2(time_mi_time,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1));
+
+ PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
+}
+
/*****************************************************************************
* Time With Time Zone ADT
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 37c202d..d72fbef 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -3726,6 +3726,47 @@ width_bucket_float8(PG_FUNCTION_ARGS)
PG_RETURN_INT32(result);
}
+Datum
+float4dist(PG_FUNCTION_ARGS)
+{
+ float4 a = PG_GETARG_FLOAT4(0);
+ float4 b = PG_GETARG_FLOAT4(1);
+ float4 r = float4_mi(a, b);
+
+ PG_RETURN_FLOAT4(Abs(r));
+}
+
+Datum
+float8dist(PG_FUNCTION_ARGS)
+{
+ float8 a = PG_GETARG_FLOAT8(0);
+ float8 b = PG_GETARG_FLOAT8(1);
+ float8 r = float8_mi(a, b);
+
+ PG_RETURN_FLOAT8(Abs(r));
+}
+
+
+Datum
+float48dist(PG_FUNCTION_ARGS)
+{
+ float4 a = PG_GETARG_FLOAT4(0);
+ float8 b = PG_GETARG_FLOAT8(1);
+ float8 r = float8_mi(a, b);
+
+ PG_RETURN_FLOAT8(Abs(r));
+}
+
+Datum
+float84dist(PG_FUNCTION_ARGS)
+{
+ float8 a = PG_GETARG_FLOAT8(0);
+ float4 b = PG_GETARG_FLOAT4(1);
+ float8 r = float8_mi(a, b);
+
+ PG_RETURN_FLOAT8(Abs(r));
+}
+
/* ========== PRIVATE ROUTINES ========== */
#ifndef HAVE_CBRT
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 04825fc..76e92ec 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -1501,3 +1501,54 @@ generate_series_int4_support(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(ret);
}
+
+Datum
+int2dist(PG_FUNCTION_ARGS)
+{
+ int16 a = PG_GETARG_INT16(0);
+ int16 b = PG_GETARG_INT16(1);
+ int16 r;
+ int16 ra;
+
+ if (pg_sub_s16_overflow(a, b, &r) ||
+ r == PG_INT16_MIN)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("smallint out of range")));
+
+ ra = Abs(r);
+
+ PG_RETURN_INT16(ra);
+}
+
+static int32
+int44_dist(int32 a, int32 b)
+{
+ int32 r;
+
+ if (pg_sub_s32_overflow(a, b, &r) ||
+ r == PG_INT32_MIN)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("integer out of range")));
+
+ return Abs(r);
+}
+
+Datum
+int4dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT32(int44_dist(PG_GETARG_INT32(0), PG_GETARG_INT32(1)));
+}
+
+Datum
+int24dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT32(int44_dist(PG_GETARG_INT16(0), PG_GETARG_INT32(1)));
+}
+
+Datum
+int42dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT32(int44_dist(PG_GETARG_INT32(0), PG_GETARG_INT16(1)));
+}
diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c
index 0ff9394..2ceb16b 100644
--- a/src/backend/utils/adt/int8.c
+++ b/src/backend/utils/adt/int8.c
@@ -1446,3 +1446,47 @@ generate_series_int8_support(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(ret);
}
+
+static int64
+int88_dist(int64 a, int64 b)
+{
+ int64 r;
+
+ if (pg_sub_s64_overflow(a, b, &r) ||
+ r == PG_INT64_MIN)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("bigint out of range")));
+
+ return Abs(r);
+}
+
+Datum
+int8dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(int88_dist(PG_GETARG_INT64(0), PG_GETARG_INT64(1)));
+}
+
+Datum
+int82dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(int88_dist(PG_GETARG_INT64(0), (int64) PG_GETARG_INT16(1)));
+}
+
+Datum
+int84dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(int88_dist(PG_GETARG_INT64(0), (int64) PG_GETARG_INT32(1)));
+}
+
+Datum
+int28dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(int88_dist((int64) PG_GETARG_INT16(0), PG_GETARG_INT64(1)));
+}
+
+Datum
+int48dist(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(int88_dist((int64) PG_GETARG_INT32(0), PG_GETARG_INT64(1)));
+}
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index bb67e01..b8f48d5 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -469,3 +469,17 @@ oidvectorgt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(cmp > 0);
}
+
+Datum
+oiddist(PG_FUNCTION_ARGS)
+{
+ Oid a = PG_GETARG_OID(0);
+ Oid b = PG_GETARG_OID(1);
+ Oid res;
+
+ if (a < b)
+ res = b - a;
+ else
+ res = a - b;
+ PG_RETURN_OID(res);
+}
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index e0ef2f7..c5d1042 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -2694,6 +2694,86 @@ timestamp_mi(PG_FUNCTION_ARGS)
PG_RETURN_INTERVAL_P(result);
}
+Datum
+timestamp_distance(PG_FUNCTION_ARGS)
+{
+ Timestamp a = PG_GETARG_TIMESTAMP(0);
+ Timestamp b = PG_GETARG_TIMESTAMP(1);
+ Interval *r;
+
+ if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b))
+ {
+ Interval *p = palloc(sizeof(Interval));
+
+ p->day = INT_MAX;
+ p->month = INT_MAX;
+ p->time = PG_INT64_MAX;
+ PG_RETURN_INTERVAL_P(p);
+ }
+ else
+ r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+ PG_RETURN_INTERVAL_P(abs_interval(r));
+}
+
+Interval *
+timestamp_dist_internal(Timestamp a, Timestamp b)
+{
+ Interval *r;
+
+ if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b))
+ {
+ r = palloc(sizeof(Interval));
+
+ r->day = INT_MAX;
+ r->month = INT_MAX;
+ r->time = PG_INT64_MAX;
+
+ return r;
+ }
+
+ r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
+ TimestampGetDatum(a),
+ TimestampGetDatum(b)));
+
+ return abs_interval(r);
+}
+
+Datum
+timestamptz_distance(PG_FUNCTION_ARGS)
+{
+ TimestampTz a = PG_GETARG_TIMESTAMPTZ(0);
+ TimestampTz b = PG_GETARG_TIMESTAMPTZ(1);
+
+ PG_RETURN_INTERVAL_P(timestamp_dist_internal(a, b));
+}
+
+Datum
+timestamp_dist_timestamptz(PG_FUNCTION_ARGS)
+{
+ Timestamp ts1 = PG_GETARG_TIMESTAMP(0);
+ TimestampTz tstz2 = PG_GETARG_TIMESTAMPTZ(1);
+ TimestampTz tstz1;
+
+ tstz1 = timestamp2timestamptz(ts1);
+
+ PG_RETURN_INTERVAL_P(timestamp_dist_internal(tstz1, tstz2));
+}
+
+Datum
+timestamptz_dist_timestamp(PG_FUNCTION_ARGS)
+{
+ TimestampTz tstz1 = PG_GETARG_TIMESTAMPTZ(0);
+ Timestamp ts2 = PG_GETARG_TIMESTAMP(1);
+ TimestampTz tstz2;
+
+ tstz2 = timestamp2timestamptz(ts2);
+
+ PG_RETURN_INTERVAL_P(timestamp_dist_internal(tstz1, tstz2));
+}
+
+
/*
* interval_justify_interval()
*
@@ -3563,6 +3643,29 @@ interval_avg(PG_FUNCTION_ARGS)
Float8GetDatum((double) N.time));
}
+Interval *
+abs_interval(Interval *a)
+{
+ static Interval zero = {0, 0, 0};
+
+ if (DatumGetBool(DirectFunctionCall2(interval_lt,
+ IntervalPGetDatum(a),
+ IntervalPGetDatum(&zero))))
+ a = DatumGetIntervalP(DirectFunctionCall1(interval_um,
+ IntervalPGetDatum(a)));
+
+ return a;
+}
+
+Datum
+interval_distance(PG_FUNCTION_ARGS)
+{
+ Datum diff = DirectFunctionCall2(interval_mi,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1));
+
+ PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
+}
/* timestamp_age()
* Calculate time difference while retaining year/month fields.
diff --git a/src/include/catalog/pg_amop.dat b/src/include/catalog/pg_amop.dat
index 0ab95d8..0e06b04 100644
--- a/src/include/catalog/pg_amop.dat
+++ b/src/include/catalog/pg_amop.dat
@@ -30,6 +30,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
amoprighttype => 'int2', amopstrategy => '5', amopopr => '>(int2,int2)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
+ amoprighttype => 'int2', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int2,int2)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int24
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
@@ -47,6 +51,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
amoprighttype => 'int4', amopstrategy => '5', amopopr => '>(int2,int4)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
+ amoprighttype => 'int4', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int2,int4)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int28
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
@@ -64,6 +72,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
amoprighttype => 'int8', amopstrategy => '5', amopopr => '>(int2,int8)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int2',
+ amoprighttype => 'int8', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int2,int8)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# default operators int4
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
@@ -81,6 +93,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
amoprighttype => 'int4', amopstrategy => '5', amopopr => '>(int4,int4)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
+ amoprighttype => 'int4', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int4,int4)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int42
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
@@ -98,6 +114,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
amoprighttype => 'int2', amopstrategy => '5', amopopr => '>(int4,int2)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
+ amoprighttype => 'int2', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int4,int2)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int48
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
@@ -115,6 +135,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
amoprighttype => 'int8', amopstrategy => '5', amopopr => '>(int4,int8)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int4',
+ amoprighttype => 'int8', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int4,int8)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# default operators int8
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
@@ -132,6 +156,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
amoprighttype => 'int8', amopstrategy => '5', amopopr => '>(int8,int8)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
+ amoprighttype => 'int8', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int8,int8)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int82
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
@@ -149,6 +177,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
amoprighttype => 'int2', amopstrategy => '5', amopopr => '>(int8,int2)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
+ amoprighttype => 'int2', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int8,int2)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators int84
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
@@ -166,6 +198,10 @@
{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
amoprighttype => 'int4', amopstrategy => '5', amopopr => '>(int8,int4)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/integer_ops', amoplefttype => 'int8',
+ amoprighttype => 'int4', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(int8,int4)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# btree oid_ops
@@ -179,6 +215,10 @@
amopstrategy => '4', amopopr => '>=(oid,oid)', amopmethod => 'btree' },
{ amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
amopstrategy => '5', amopopr => '>(oid,oid)', amopmethod => 'btree' },
+{ amopfamily => 'btree/oid_ops', amoplefttype => 'oid',
+ amoprighttype => 'oid', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(oid,oid)', amopmethod => 'btree',
+ amopsortfamily => 'btree/oid_ops' },
# btree tid_ops
@@ -229,6 +269,10 @@
{ amopfamily => 'btree/float_ops', amoplefttype => 'float4',
amoprighttype => 'float4', amopstrategy => '5', amopopr => '>(float4,float4)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/float_ops', amoplefttype => 'float4',
+ amoprighttype => 'float4', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(float4,float4)', amopmethod => 'btree',
+ amopsortfamily => 'btree/float_ops' },
# crosstype operators float48
{ amopfamily => 'btree/float_ops', amoplefttype => 'float4',
@@ -246,6 +290,10 @@
{ amopfamily => 'btree/float_ops', amoplefttype => 'float4',
amoprighttype => 'float8', amopstrategy => '5', amopopr => '>(float4,float8)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/float_ops', amoplefttype => 'float4',
+ amoprighttype => 'float8', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(float4,float8)', amopmethod => 'btree',
+ amopsortfamily => 'btree/float_ops' },
# default operators float8
{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
@@ -263,6 +311,10 @@
{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
amoprighttype => 'float8', amopstrategy => '5', amopopr => '>(float8,float8)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
+ amoprighttype => 'float8', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(float8,float8)', amopmethod => 'btree',
+ amopsortfamily => 'btree/float_ops' },
# crosstype operators float84
{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
@@ -280,6 +332,10 @@
{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
amoprighttype => 'float4', amopstrategy => '5', amopopr => '>(float8,float4)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/float_ops', amoplefttype => 'float8',
+ amoprighttype => 'float4', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(float8,float4)', amopmethod => 'btree',
+ amopsortfamily => 'btree/float_ops' },
# btree char_ops
@@ -416,6 +472,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
amoprighttype => 'date', amopstrategy => '5', amopopr => '>(date,date)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
+ amoprighttype => 'date', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(date,date)', amopmethod => 'btree',
+ amopsortfamily => 'btree/integer_ops' },
# crosstype operators vs timestamp
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
@@ -433,6 +493,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
amoprighttype => 'timestamp', amopstrategy => '5',
amopopr => '>(date,timestamp)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
+ amoprighttype => 'timestamp', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(date,timestamp)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# crosstype operators vs timestamptz
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
@@ -450,6 +514,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
amoprighttype => 'timestamptz', amopstrategy => '5',
amopopr => '>(date,timestamptz)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'date',
+ amoprighttype => 'timestamptz', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(date,timestamptz)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# default operators timestamp
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
@@ -467,6 +535,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
amoprighttype => 'timestamp', amopstrategy => '5',
amopopr => '>(timestamp,timestamp)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
+ amoprighttype => 'timestamp', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamp,timestamp)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# crosstype operators vs date
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
@@ -484,6 +556,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
amoprighttype => 'date', amopstrategy => '5', amopopr => '>(timestamp,date)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
+ amoprighttype => 'date', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamp,date)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# crosstype operators vs timestamptz
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
@@ -501,6 +577,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
amoprighttype => 'timestamptz', amopstrategy => '5',
amopopr => '>(timestamp,timestamptz)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamp',
+ amoprighttype => 'timestamptz', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamp,timestamptz)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# default operators timestamptz
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
@@ -518,6 +598,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
amoprighttype => 'timestamptz', amopstrategy => '5',
amopopr => '>(timestamptz,timestamptz)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
+ amoprighttype => 'timestamptz', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamptz,timestamptz)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# crosstype operators vs date
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
@@ -535,6 +619,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
amoprighttype => 'date', amopstrategy => '5',
amopopr => '>(timestamptz,date)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
+ amoprighttype => 'date', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamptz,date)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# crosstype operators vs timestamp
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
@@ -552,6 +640,10 @@
{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
amoprighttype => 'timestamp', amopstrategy => '5',
amopopr => '>(timestamptz,timestamp)', amopmethod => 'btree' },
+{ amopfamily => 'btree/datetime_ops', amoplefttype => 'timestamptz',
+ amoprighttype => 'timestamp', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(timestamptz,timestamp)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# btree time_ops
@@ -570,6 +662,10 @@
{ amopfamily => 'btree/time_ops', amoplefttype => 'time',
amoprighttype => 'time', amopstrategy => '5', amopopr => '>(time,time)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/time_ops', amoplefttype => 'time',
+ amoprighttype => 'time', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(time,time)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# btree timetz_ops
@@ -606,6 +702,10 @@
{ amopfamily => 'btree/interval_ops', amoplefttype => 'interval',
amoprighttype => 'interval', amopstrategy => '5',
amopopr => '>(interval,interval)', amopmethod => 'btree' },
+{ amopfamily => 'btree/interval_ops', amoplefttype => 'interval',
+ amoprighttype => 'interval', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(interval,interval)', amopmethod => 'btree',
+ amopsortfamily => 'btree/interval_ops' },
# btree macaddr
@@ -781,6 +881,10 @@
{ amopfamily => 'btree/money_ops', amoplefttype => 'money',
amoprighttype => 'money', amopstrategy => '5', amopopr => '>(money,money)',
amopmethod => 'btree' },
+{ amopfamily => 'btree/money_ops', amoplefttype => 'money',
+ amoprighttype => 'money', amopstrategy => '6', amoppurpose => 'o',
+ amopopr => '<->(money,money)', amopmethod => 'btree',
+ amopsortfamily => 'btree/money_ops' },
# btree array_ops
diff --git a/src/include/catalog/pg_operator.dat b/src/include/catalog/pg_operator.dat
index 06aec07..914ca76 100644
--- a/src/include/catalog/pg_operator.dat
+++ b/src/include/catalog/pg_operator.dat
@@ -2851,6 +2851,114 @@
oprname => '-', oprleft => 'pg_lsn', oprright => 'pg_lsn',
oprresult => 'numeric', oprcode => 'pg_lsn_mi' },
+# distance operators
+{ oid => '4217', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int2',
+ oprright => 'int2', oprresult => 'int2', oprcom => '<->(int2,int2)',
+ oprcode => 'int2dist'},
+{ oid => '4218', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int4',
+ oprright => 'int4', oprresult => 'int4', oprcom => '<->(int4,int4)',
+ oprcode => 'int4dist'},
+{ oid => '4219', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int8',
+ oprright => 'int8', oprresult => 'int8', oprcom => '<->(int8,int8)',
+ oprcode => 'int8dist'},
+{ oid => '4220', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'oid',
+ oprright => 'oid', oprresult => 'oid', oprcom => '<->(oid,oid)',
+ oprcode => 'oiddist'},
+{ oid => '4221', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'float4',
+ oprright => 'float4', oprresult => 'float4', oprcom => '<->(float4,float4)',
+ oprcode => 'float4dist'},
+{ oid => '4222', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'float8',
+ oprright => 'float8', oprresult => 'float8', oprcom => '<->(float8,float8)',
+ oprcode => 'float8dist'},
+{ oid => '4223', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'money',
+ oprright => 'money', oprresult => 'money', oprcom => '<->(money,money)',
+ oprcode => 'cash_distance'},
+{ oid => '4224', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'date',
+ oprright => 'date', oprresult => 'int4', oprcom => '<->(date,date)',
+ oprcode => 'date_distance'},
+{ oid => '4225', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'time',
+ oprright => 'time', oprresult => 'interval', oprcom => '<->(time,time)',
+ oprcode => 'time_distance'},
+{ oid => '4226', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamp',
+ oprright => 'timestamp', oprresult => 'interval', oprcom => '<->(timestamp,timestamp)',
+ oprcode => 'timestamp_distance'},
+{ oid => '4227', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamptz',
+ oprright => 'timestamptz', oprresult => 'interval', oprcom => '<->(timestamptz,timestamptz)',
+ oprcode => 'timestamptz_distance'},
+{ oid => '4228', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'interval',
+ oprright => 'interval', oprresult => 'interval', oprcom => '<->(interval,interval)',
+ oprcode => 'interval_distance'},
+
+# cross-type distance operators
+{ oid => '4229', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int2',
+ oprright => 'int4', oprresult => 'int4', oprcom => '<->(int4,int2)',
+ oprcode => 'int24dist'},
+{ oid => '4230', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int4',
+ oprright => 'int2', oprresult => 'int4', oprcom => '<->(int2,int4)',
+ oprcode => 'int42dist'},
+{ oid => '4231', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int2',
+ oprright => 'int8', oprresult => 'int8', oprcom => '<->(int8,int2)',
+ oprcode => 'int28dist'},
+{ oid => '4232', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int8',
+ oprright => 'int2', oprresult => 'int8', oprcom => '<->(int2,int8)',
+ oprcode => 'int82dist'},
+{ oid => '4233', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int4',
+ oprright => 'int8', oprresult => 'int8', oprcom => '<->(int8,int4)',
+ oprcode => 'int48dist'},
+{ oid => '4234', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'int8',
+ oprright => 'int4', oprresult => 'int8', oprcom => '<->(int4,int8)',
+ oprcode => 'int84dist'},
+{ oid => '4235', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'float4',
+ oprright => 'float8', oprresult => 'float8', oprcom => '<->(float8,float4)',
+ oprcode => 'float48dist'},
+{ oid => '4236', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'float8',
+ oprright => 'float4', oprresult => 'float8', oprcom => '<->(float4,float8)',
+ oprcode => 'float84dist'},
+{ oid => '4237', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'date',
+ oprright => 'timestamp', oprresult => 'interval', oprcom => '<->(timestamp,date)',
+ oprcode => 'date_dist_timestamp'},
+{ oid => '4238', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamp',
+ oprright => 'date', oprresult => 'interval', oprcom => '<->(date,timestamp)',
+ oprcode => 'timestamp_dist_date'},
+{ oid => '4239', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'date',
+ oprright => 'timestamptz', oprresult => 'interval', oprcom => '<->(timestamptz,date)',
+ oprcode => 'date_dist_timestamptz'},
+{ oid => '4240', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamptz',
+ oprright => 'date', oprresult => 'interval', oprcom => '<->(date,timestamptz)',
+ oprcode => 'timestamptz_dist_date'},
+{ oid => '4241', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamp',
+ oprright => 'timestamptz', oprresult => 'interval', oprcom => '<->(timestamptz,timestamp)',
+ oprcode => 'timestamp_dist_timestamptz'},
+{ oid => '4242', descr => 'distance between',
+ oprname => '<->', oprcanmerge => 'f', oprcanhash => 'f', oprleft => 'timestamptz',
+ oprright => 'timestamp', oprresult => 'interval', oprcom => '<->(timestamp,timestamptz)',
+ oprcode => 'timestamptz_dist_timestamp'},
+
# enum operators
{ oid => '3516', descr => 'equal',
oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'anyenum',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index a4e173b..96d5db0 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10534,4 +10534,90 @@
proname => 'pg_partition_root', prorettype => 'regclass',
proargtypes => 'regclass', prosrc => 'pg_partition_root' },
+# distance functions
+{ oid => '4243',
+ proname => 'int2dist', prorettype => 'int2',
+ proargtypes => 'int2 int2', prosrc => 'int2dist' },
+{ oid => '4244',
+ proname => 'int4dist', prorettype => 'int4',
+ proargtypes => 'int4 int4', prosrc => 'int4dist' },
+{ oid => '4245',
+ proname => 'int8dist', prorettype => 'int8',
+ proargtypes => 'int8 int8', prosrc => 'int8dist' },
+{ oid => '4246',
+ proname => 'oiddist', proleakproof => 't', prorettype => 'oid',
+ proargtypes => 'oid oid', prosrc => 'oiddist' },
+{ oid => '4247',
+ proname => 'float4dist', prorettype => 'float4',
+ proargtypes => 'float4 float4', prosrc => 'float4dist' },
+{ oid => '4248',
+ proname => 'float8dist', prorettype => 'float8',
+ proargtypes => 'float8 float8', prosrc => 'float8dist' },
+{ oid => '4249',
+ proname => 'cash_distance', prorettype => 'money',
+ proargtypes => 'money money', prosrc => 'cash_distance' },
+{ oid => '4250',
+ proname => 'date_distance', prorettype => 'int4',
+ proargtypes => 'date date', prosrc => 'date_distance' },
+{ oid => '4251',
+ proname => 'time_distance', prorettype => 'interval',
+ proargtypes => 'time time', prosrc => 'time_distance' },
+{ oid => '4252',
+ proname => 'timestamp_distance', prorettype => 'interval',
+ proargtypes => 'timestamp timestamp', prosrc => 'timestamp_distance' },
+{ oid => '4253',
+ proname => 'timestamptz_distance', prorettype => 'interval',
+ proargtypes => 'timestamptz timestamptz', prosrc => 'timestamptz_distance' },
+{ oid => '4254',
+ proname => 'interval_distance', prorettype => 'interval',
+ proargtypes => 'interval interval', prosrc => 'interval_distance' },
+
+# cross-type distance functions
+{ oid => '4255',
+ proname => 'int24dist', prorettype => 'int4',
+ proargtypes => 'int2 int4', prosrc => 'int24dist' },
+{ oid => '4256',
+ proname => 'int28dist', prorettype => 'int8',
+ proargtypes => 'int2 int8', prosrc => 'int28dist' },
+{ oid => '4257',
+ proname => 'int42dist', prorettype => 'int4',
+ proargtypes => 'int4 int2', prosrc => 'int42dist' },
+{ oid => '4258',
+ proname => 'int48dist', prorettype => 'int8',
+ proargtypes => 'int4 int8', prosrc => 'int48dist' },
+{ oid => '4259',
+ proname => 'int82dist', prorettype => 'int8',
+ proargtypes => 'int8 int2', prosrc => 'int82dist' },
+{ oid => '4260',
+ proname => 'int84dist', prorettype => 'int8',
+ proargtypes => 'int8 int4', prosrc => 'int84dist' },
+{ oid => '4261',
+ proname => 'float48dist', prorettype => 'float8',
+ proargtypes => 'float4 float8', prosrc => 'float48dist' },
+{ oid => '4262',
+ proname => 'float84dist', prorettype => 'float8',
+ proargtypes => 'float8 float4', prosrc => 'float84dist' },
+{ oid => '4263',
+ proname => 'date_dist_timestamp', prorettype => 'interval',
+ proargtypes => 'date timestamp', prosrc => 'date_dist_timestamp' },
+{ oid => '4264',
+ proname => 'date_dist_timestamptz', provolatile => 's',
+ prorettype => 'interval', proargtypes => 'date timestamptz',
+ prosrc => 'date_dist_timestamptz' },
+{ oid => '4265',
+ proname => 'timestamp_dist_date', prorettype => 'interval',
+ proargtypes => 'timestamp date', prosrc => 'timestamp_dist_date' },
+{ oid => '4266',
+ proname => 'timestamp_dist_timestamptz', provolatile => 's',
+ prorettype => 'interval', proargtypes => 'timestamp timestamptz',
+ prosrc => 'timestamp_dist_timestamptz' },
+{ oid => '4267',
+ proname => 'timestamptz_dist_date', provolatile => 's',
+ prorettype => 'interval', proargtypes => 'timestamptz date',
+ prosrc => 'timestamptz_dist_date' },
+{ oid => '4268',
+ proname => 'timestamptz_dist_timestamp', provolatile => 's',
+ prorettype => 'interval', proargtypes => 'timestamptz timestamp',
+ prosrc => 'timestamptz_dist_timestamp' },
+
]
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 87f819e..01d2284 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -338,4 +338,6 @@ extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs,
int n);
extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl);
+extern Interval *abs_interval(Interval *a);
+
#endif /* DATETIME_H */
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index aeb89dc..438a5eb 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -93,9 +93,11 @@ extern Timestamp SetEpochTimestamp(void);
extern void GetEpochTime(struct pg_tm *tm);
extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2);
+extern Interval *timestamp_dist_internal(Timestamp a, Timestamp b);
-/* timestamp comparison works for timestamptz also */
+/* timestamp comparison and distance works for timestamptz also */
#define timestamptz_cmp_internal(dt1,dt2) timestamp_cmp_internal(dt1, dt2)
+#define timestamptz_dist_internal(dt1,dt2) timestamp_dist_internal(dt1, dt2)
extern int isoweek2j(int year, int week);
extern void isoweek2date(int woy, int *year, int *mon, int *mday);
diff --git a/src/test/regress/expected/amutils.out b/src/test/regress/expected/amutils.out
index 4570a39..630dc6b 100644
--- a/src/test/regress/expected/amutils.out
+++ b/src/test/regress/expected/amutils.out
@@ -24,7 +24,7 @@ select prop,
nulls_first | | | f
nulls_last | | | t
orderable | | | t
- distance_orderable | | | f
+ distance_orderable | | | t
returnable | | | t
search_array | | | t
search_nulls | | | t
@@ -100,7 +100,7 @@ select prop,
nulls_first | f | f | f | f | f | f | f
nulls_last | t | f | f | f | f | f | f
orderable | t | f | f | f | f | f | f
- distance_orderable | f | f | t | f | t | f | f
+ distance_orderable | t | f | t | f | t | f | f
returnable | t | f | f | t | t | f | f
search_array | t | f | f | f | f | f | f
search_nulls | t | f | t | t | t | f | t
@@ -231,7 +231,7 @@ select col, prop, pg_index_column_has_property(o, col, prop)
1 | desc | f
1 | nulls_first | f
1 | nulls_last | t
- 1 | distance_orderable | f
+ 1 | distance_orderable | t
1 | returnable | t
1 | bogus |
2 | orderable | f
diff --git a/src/test/regress/expected/date.out b/src/test/regress/expected/date.out
index 1bcc946..b9b819c 100644
--- a/src/test/regress/expected/date.out
+++ b/src/test/regress/expected/date.out
@@ -1477,3 +1477,64 @@ select make_time(10, 55, 100.1);
ERROR: time field value out of range: 10:55:100.1
select make_time(24, 0, 2.1);
ERROR: time field value out of range: 24:00:2.1
+-- distance operators
+SELECT '' AS "Fifteen", f1 <-> date '2001-02-03' AS "Distance" FROM DATE_TBL;
+ Fifteen | Distance
+---------+----------
+ | 16006
+ | 15941
+ | 1802
+ | 1801
+ | 1800
+ | 1799
+ | 1436
+ | 1435
+ | 1434
+ | 308
+ | 307
+ | 306
+ | 13578
+ | 13944
+ | 14311
+(15 rows)
+
+SELECT '' AS "Fifteen", f1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM DATE_TBL;
+ Fifteen | Distance
+---------+---------------------------------------
+ | @ 16006 days 1 hour 23 mins 45 secs
+ | @ 15941 days 1 hour 23 mins 45 secs
+ | @ 1802 days 1 hour 23 mins 45 secs
+ | @ 1801 days 1 hour 23 mins 45 secs
+ | @ 1800 days 1 hour 23 mins 45 secs
+ | @ 1799 days 1 hour 23 mins 45 secs
+ | @ 1436 days 1 hour 23 mins 45 secs
+ | @ 1435 days 1 hour 23 mins 45 secs
+ | @ 1434 days 1 hour 23 mins 45 secs
+ | @ 308 days 1 hour 23 mins 45 secs
+ | @ 307 days 1 hour 23 mins 45 secs
+ | @ 306 days 1 hour 23 mins 45 secs
+ | @ 13577 days 22 hours 36 mins 15 secs
+ | @ 13943 days 22 hours 36 mins 15 secs
+ | @ 14310 days 22 hours 36 mins 15 secs
+(15 rows)
+
+SELECT '' AS "Fifteen", f1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM DATE_TBL;
+ Fifteen | Distance
+---------+---------------------------------------
+ | @ 16005 days 14 hours 23 mins 45 secs
+ | @ 15940 days 14 hours 23 mins 45 secs
+ | @ 1801 days 14 hours 23 mins 45 secs
+ | @ 1800 days 14 hours 23 mins 45 secs
+ | @ 1799 days 14 hours 23 mins 45 secs
+ | @ 1798 days 14 hours 23 mins 45 secs
+ | @ 1435 days 14 hours 23 mins 45 secs
+ | @ 1434 days 14 hours 23 mins 45 secs
+ | @ 1433 days 14 hours 23 mins 45 secs
+ | @ 307 days 14 hours 23 mins 45 secs
+ | @ 306 days 14 hours 23 mins 45 secs
+ | @ 305 days 15 hours 23 mins 45 secs
+ | @ 13578 days 8 hours 36 mins 15 secs
+ | @ 13944 days 8 hours 36 mins 15 secs
+ | @ 14311 days 8 hours 36 mins 15 secs
+(15 rows)
+
diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out
index cf78277..ce29924e 100644
--- a/src/test/regress/expected/float4.out
+++ b/src/test/regress/expected/float4.out
@@ -273,6 +273,26 @@ SELECT '' AS five, * FROM FLOAT4_TBL;
| -1.2345679e-20
(5 rows)
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3' AS dist FROM FLOAT4_TBL f;
+ five | f1 | dist
+------+----------------+---------------
+ | 0 | 1004.3
+ | -34.84 | 1039.14
+ | -1004.3 | 2008.6
+ | -1.2345679e+20 | 1.2345679e+20
+ | -1.2345679e-20 | 1004.3
+(5 rows)
+
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float8 AS dist FROM FLOAT4_TBL f;
+ five | f1 | dist
+------+----------------+------------------------
+ | 0 | 1004.3
+ | -34.84 | 1039.1400001525878
+ | -1004.3 | 2008.5999877929687
+ | -1.2345679e+20 | 1.2345678955701443e+20
+ | -1.2345679e-20 | 1004.3
+(5 rows)
+
-- test edge-case coercions to integer
SELECT '32767.4'::float4::int2;
int2
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index c3a6f53..5485c19 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -413,6 +413,27 @@ SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f;
| 1.2345678901234e-200 | 2.3112042409018e-67
(5 rows)
+-- distance
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float8 AS dist FROM FLOAT8_TBL f;
+ five | f1 | dist
+------+----------------------+----------------------
+ | 0 | 1004.3
+ | 1004.3 | 0
+ | -34.84 | 1039.14
+ | 1.2345678901234e+200 | 1.2345678901234e+200
+ | 1.2345678901234e-200 | 1004.3
+(5 rows)
+
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float4 AS dist FROM FLOAT8_TBL f;
+ five | f1 | dist
+------+----------------------+----------------------
+ | 0 | 1004.29998779297
+ | 1004.3 | 1.22070312045253e-05
+ | -34.84 | 1039.13998779297
+ | 1.2345678901234e+200 | 1.2345678901234e+200
+ | 1.2345678901234e-200 | 1004.29998779297
+(5 rows)
+
SELECT '' AS five, * FROM FLOAT8_TBL;
five | f1
------+----------------------
diff --git a/src/test/regress/expected/int2.out b/src/test/regress/expected/int2.out
index 8c255b9..0edc57e 100644
--- a/src/test/regress/expected/int2.out
+++ b/src/test/regress/expected/int2.out
@@ -242,6 +242,39 @@ SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i;
| -32767 | -16383
(5 rows)
+-- distance
+SELECT '' AS five, i.f1, i.f1 <-> int2 '2' AS x FROM INT2_TBL i;
+ERROR: smallint out of range
+SELECT '' AS four, i.f1, i.f1 <-> int2 '2' AS x FROM INT2_TBL i
+WHERE f1 > -32767;
+ four | f1 | x
+------+-------+-------
+ | 0 | 2
+ | 1234 | 1232
+ | -1234 | 1236
+ | 32767 | 32765
+(4 rows)
+
+SELECT '' AS five, i.f1, i.f1 <-> int4 '2' AS x FROM INT2_TBL i;
+ five | f1 | x
+------+--------+-------
+ | 0 | 2
+ | 1234 | 1232
+ | -1234 | 1236
+ | 32767 | 32765
+ | -32767 | 32769
+(5 rows)
+
+SELECT '' AS five, i.f1, i.f1 <-> int8 '2' AS x FROM INT2_TBL i;
+ five | f1 | x
+------+--------+-------
+ | 0 | 2
+ | 1234 | 1232
+ | -1234 | 1236
+ | 32767 | 32765
+ | -32767 | 32769
+(5 rows)
+
-- corner cases
SELECT (-1::int2<<15)::text;
text
diff --git a/src/test/regress/expected/int4.out b/src/test/regress/expected/int4.out
index bda7a8d..3735dbc 100644
--- a/src/test/regress/expected/int4.out
+++ b/src/test/regress/expected/int4.out
@@ -247,6 +247,38 @@ SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i;
| -2147483647 | -1073741823
(5 rows)
+SELECT '' AS five, i.f1, i.f1 <-> int2 '2' AS x FROM INT4_TBL i;
+ERROR: integer out of range
+SELECT '' AS four, i.f1, i.f1 <-> int2 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+ four | f1 | x
+------+------------+------------
+ | 0 | 2
+ | 123456 | 123454
+ | -123456 | 123458
+ | 2147483647 | 2147483645
+(4 rows)
+
+SELECT '' AS four, i.f1, i.f1 <-> int4 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+ four | f1 | x
+------+------------+------------
+ | 0 | 2
+ | 123456 | 123454
+ | -123456 | 123458
+ | 2147483647 | 2147483645
+(4 rows)
+
+SELECT '' AS five, i.f1, i.f1 <-> int8 '2' AS x FROM INT4_TBL i;
+ five | f1 | x
+------+-------------+------------
+ | 0 | 2
+ | 123456 | 123454
+ | -123456 | 123458
+ | 2147483647 | 2147483645
+ | -2147483647 | 2147483649
+(5 rows)
+
--
-- more complex expressions
--
diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out
index 8447a28..d56886a 100644
--- a/src/test/regress/expected/int8.out
+++ b/src/test/regress/expected/int8.out
@@ -432,6 +432,37 @@ SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 A
4567890123457035 | -4567890123456543 | 1123700970370370094 | 0
(5 rows)
+-- distance
+SELECT '' AS five, q2, q2 <-> int2 '123' AS dist FROM INT8_TBL i;
+ five | q2 | dist
+------+-------------------+------------------
+ | 456 | 333
+ | 4567890123456789 | 4567890123456666
+ | 123 | 0
+ | 4567890123456789 | 4567890123456666
+ | -4567890123456789 | 4567890123456912
+(5 rows)
+
+SELECT '' AS five, q2, q2 <-> int4 '123' AS dist FROM INT8_TBL i;
+ five | q2 | dist
+------+-------------------+------------------
+ | 456 | 333
+ | 4567890123456789 | 4567890123456666
+ | 123 | 0
+ | 4567890123456789 | 4567890123456666
+ | -4567890123456789 | 4567890123456912
+(5 rows)
+
+SELECT '' AS five, q2, q2 <-> int8 '123' AS dist FROM INT8_TBL i;
+ five | q2 | dist
+------+-------------------+------------------
+ | 456 | 333
+ | 4567890123456789 | 4567890123456666
+ | 123 | 0
+ | 4567890123456789 | 4567890123456666
+ | -4567890123456789 | 4567890123456912
+(5 rows)
+
SELECT q2, abs(q2) FROM INT8_TBL;
q2 | abs
-------------------+------------------
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out
index f88f345..cb95adf 100644
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -207,6 +207,21 @@ SELECT '' AS fortyfive, r1.*, r2.*
| 34 years | 6 years
(45 rows)
+SELECT '' AS ten, f1 <-> interval '@ 2 day 3 hours' FROM INTERVAL_TBL;
+ ten | ?column?
+-----+----------------------------
+ | 2 days 02:59:00
+ | 2 days -02:00:00
+ | 8 days -03:00:00
+ | 34 years -2 days -03:00:00
+ | 3 mons -2 days -03:00:00
+ | 2 days 03:00:14
+ | 1 day 00:56:56
+ | 6 years -2 days -03:00:00
+ | 5 mons -2 days -03:00:00
+ | 5 mons -2 days +09:00:00
+(10 rows)
+
-- Test intervals that are large enough to overflow 64 bits in comparisons
CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval);
INSERT INTO INTERVAL_TBL_OF (f1) VALUES
diff --git a/src/test/regress/expected/money.out b/src/test/regress/expected/money.out
index ab86595..fb2a489 100644
--- a/src/test/regress/expected/money.out
+++ b/src/test/regress/expected/money.out
@@ -123,6 +123,12 @@ SELECT m / 2::float4 FROM money_data;
$61.50
(1 row)
+SELECT m <-> '$123.45' FROM money_data;
+ ?column?
+----------
+ $0.45
+(1 row)
+
-- All true
SELECT m = '$123.00' FROM money_data;
?column?
diff --git a/src/test/regress/expected/oid.out b/src/test/regress/expected/oid.out
index 1eab9cc..5339a48 100644
--- a/src/test/regress/expected/oid.out
+++ b/src/test/regress/expected/oid.out
@@ -119,4 +119,17 @@ SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 > '1234';
| 99999999
(3 rows)
+SELECT '' AS eight, f1, f1 <-> oid '123' FROM OID_TBL;
+ eight | f1 | ?column?
+-------+------------+------------
+ | 1234 | 1111
+ | 1235 | 1112
+ | 987 | 864
+ | 4294966256 | 4294966133
+ | 99999999 | 99999876
+ | 5 | 118
+ | 10 | 113
+ | 15 | 108
+(8 rows)
+
DROP TABLE OID_TBL;
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index ce25ee0..e637420 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -750,6 +750,7 @@ macaddr8_gt(macaddr8,macaddr8)
macaddr8_ge(macaddr8,macaddr8)
macaddr8_ne(macaddr8,macaddr8)
macaddr8_cmp(macaddr8,macaddr8)
+oiddist(oid,oid)
-- restore normal output mode
\a\t
-- List of functions used by libpq's fe-lobj.c
@@ -1332,7 +1333,7 @@ WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND
ao.amoprighttype = ap.amprocrighttype AND
ap.amprocnum = 1 AND
(pp.provolatile != po.provolatile OR
- pp.proleakproof != po.proleakproof)
+ (NOT pp.proleakproof AND po.proleakproof))
ORDER BY 1;
proc | vp | lp | opr | vo | lo
-------------------------------------------+----+----+-------------------------------+----+----
@@ -1862,6 +1863,7 @@ ORDER BY 1, 2, 3;
403 | 5 | *>
403 | 5 | >
403 | 5 | ~>~
+ 403 | 6 | <->
405 | 1 | =
783 | 1 | <<
783 | 1 | @@
@@ -1971,7 +1973,7 @@ ORDER BY 1, 2, 3;
4000 | 26 | >>
4000 | 27 | >>=
4000 | 28 | ^@
-(123 rows)
+(124 rows)
-- Check that all opclass search operators have selectivity estimators.
-- This is not absolutely required, but it seems a reasonable thing
diff --git a/src/test/regress/expected/time.out b/src/test/regress/expected/time.out
index 8e0afe6..ee74faa 100644
--- a/src/test/regress/expected/time.out
+++ b/src/test/regress/expected/time.out
@@ -86,3 +86,19 @@ ERROR: operator is not unique: time without time zone + time without time zone
LINE 1: SELECT f1 + time '00:01' AS "Illegal" FROM TIME_TBL;
^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts.
+-- distance
+SELECT f1 AS "Ten", f1 <-> time '01:23:45' AS "Distance" FROM TIME_TBL;
+ Ten | Distance
+-------------+-------------------------------
+ 00:00:00 | @ 1 hour 23 mins 45 secs
+ 01:00:00 | @ 23 mins 45 secs
+ 02:03:00 | @ 39 mins 15 secs
+ 11:59:00 | @ 10 hours 35 mins 15 secs
+ 12:00:00 | @ 10 hours 36 mins 15 secs
+ 12:01:00 | @ 10 hours 37 mins 15 secs
+ 23:59:00 | @ 22 hours 35 mins 15 secs
+ 23:59:59.99 | @ 22 hours 36 mins 14.99 secs
+ 15:36:39 | @ 14 hours 12 mins 54 secs
+ 15:36:39 | @ 14 hours 12 mins 54 secs
+(10 rows)
+
diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out
index 4a2fabd..dcb4205 100644
--- a/src/test/regress/expected/timestamp.out
+++ b/src/test/regress/expected/timestamp.out
@@ -1604,3 +1604,214 @@ SELECT make_timestamp(2014,12,28,6,30,45.887);
Sun Dec 28 06:30:45.887 2014
(1 row)
+-- distance operators
+SELECT '' AS "0", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMP_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+---------------------------------------
+ | @ 11356 days
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 58 secs
+ | @ 1453 days 6 hours 27 mins 58.6 secs
+ | @ 1453 days 6 hours 27 mins 58.5 secs
+ | @ 1453 days 6 hours 27 mins 58.4 secs
+ | @ 1493 days
+ | @ 1492 days 20 hours 55 mins 55 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1333 days 6 hours 27 mins 59 secs
+ | @ 231 days 18 hours 19 mins 20 secs
+ | @ 324 days 15 hours 45 mins 59 secs
+ | @ 324 days 10 hours 45 mins 58 secs
+ | @ 324 days 11 hours 45 mins 57 secs
+ | @ 324 days 20 hours 45 mins 56 secs
+ | @ 324 days 21 hours 45 mins 55 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 28 mins
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1333 days 5 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1452 days 6 hours 27 mins 59 secs
+ | @ 1451 days 6 hours 27 mins 59 secs
+ | @ 1450 days 6 hours 27 mins 59 secs
+ | @ 1449 days 6 hours 27 mins 59 secs
+ | @ 1448 days 6 hours 27 mins 59 secs
+ | @ 1447 days 6 hours 27 mins 59 secs
+ | @ 765901 days 6 hours 27 mins 59 secs
+ | @ 695407 days 6 hours 27 mins 59 secs
+ | @ 512786 days 6 hours 27 mins 59 secs
+ | @ 330165 days 6 hours 27 mins 59 secs
+ | @ 111019 days 6 hours 27 mins 59 secs
+ | @ 74495 days 6 hours 27 mins 59 secs
+ | @ 37971 days 6 hours 27 mins 59 secs
+ | @ 1447 days 6 hours 27 mins 59 secs
+ | @ 35077 days 17 hours 32 mins 1 sec
+ | @ 1801 days 6 hours 27 mins 59 secs
+ | @ 1800 days 6 hours 27 mins 59 secs
+ | @ 1799 days 6 hours 27 mins 59 secs
+ | @ 1495 days 6 hours 27 mins 59 secs
+ | @ 1494 days 6 hours 27 mins 59 secs
+ | @ 1493 days 6 hours 27 mins 59 secs
+ | @ 1435 days 6 hours 27 mins 59 secs
+ | @ 1434 days 6 hours 27 mins 59 secs
+ | @ 1130 days 6 hours 27 mins 59 secs
+ | @ 1129 days 6 hours 27 mins 59 secs
+ | @ 399 days 6 hours 27 mins 59 secs
+ | @ 398 days 6 hours 27 mins 59 secs
+ | @ 33 days 6 hours 27 mins 59 secs
+ | @ 32 days 6 hours 27 mins 59 secs
+(63 rows)
+
+SELECT '' AS "0", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMP_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+---------------------------------------
+ | @ 11356 days 1 hour 23 mins 45 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 43 secs
+ | @ 1453 days 7 hours 51 mins 43.6 secs
+ | @ 1453 days 7 hours 51 mins 43.5 secs
+ | @ 1453 days 7 hours 51 mins 43.4 secs
+ | @ 1493 days 1 hour 23 mins 45 secs
+ | @ 1492 days 22 hours 19 mins 40 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1333 days 7 hours 51 mins 44 secs
+ | @ 231 days 16 hours 55 mins 35 secs
+ | @ 324 days 17 hours 9 mins 44 secs
+ | @ 324 days 12 hours 9 mins 43 secs
+ | @ 324 days 13 hours 9 mins 42 secs
+ | @ 324 days 22 hours 9 mins 41 secs
+ | @ 324 days 23 hours 9 mins 40 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 45 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1333 days 6 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1452 days 7 hours 51 mins 44 secs
+ | @ 1451 days 7 hours 51 mins 44 secs
+ | @ 1450 days 7 hours 51 mins 44 secs
+ | @ 1449 days 7 hours 51 mins 44 secs
+ | @ 1448 days 7 hours 51 mins 44 secs
+ | @ 1447 days 7 hours 51 mins 44 secs
+ | @ 765901 days 7 hours 51 mins 44 secs
+ | @ 695407 days 7 hours 51 mins 44 secs
+ | @ 512786 days 7 hours 51 mins 44 secs
+ | @ 330165 days 7 hours 51 mins 44 secs
+ | @ 111019 days 7 hours 51 mins 44 secs
+ | @ 74495 days 7 hours 51 mins 44 secs
+ | @ 37971 days 7 hours 51 mins 44 secs
+ | @ 1447 days 7 hours 51 mins 44 secs
+ | @ 35077 days 16 hours 8 mins 16 secs
+ | @ 1801 days 7 hours 51 mins 44 secs
+ | @ 1800 days 7 hours 51 mins 44 secs
+ | @ 1799 days 7 hours 51 mins 44 secs
+ | @ 1495 days 7 hours 51 mins 44 secs
+ | @ 1494 days 7 hours 51 mins 44 secs
+ | @ 1493 days 7 hours 51 mins 44 secs
+ | @ 1435 days 7 hours 51 mins 44 secs
+ | @ 1434 days 7 hours 51 mins 44 secs
+ | @ 1130 days 7 hours 51 mins 44 secs
+ | @ 1129 days 7 hours 51 mins 44 secs
+ | @ 399 days 7 hours 51 mins 44 secs
+ | @ 398 days 7 hours 51 mins 44 secs
+ | @ 33 days 7 hours 51 mins 44 secs
+ | @ 32 days 7 hours 51 mins 44 secs
+(63 rows)
+
+SELECT '' AS "0", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMP_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+----------------------------------------
+ | @ 11355 days 14 hours 23 mins 45 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 43 secs
+ | @ 1452 days 20 hours 51 mins 43.6 secs
+ | @ 1452 days 20 hours 51 mins 43.5 secs
+ | @ 1452 days 20 hours 51 mins 43.4 secs
+ | @ 1492 days 14 hours 23 mins 45 secs
+ | @ 1492 days 11 hours 19 mins 40 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1332 days 21 hours 51 mins 44 secs
+ | @ 232 days 2 hours 55 mins 35 secs
+ | @ 324 days 6 hours 9 mins 44 secs
+ | @ 324 days 1 hour 9 mins 43 secs
+ | @ 324 days 2 hours 9 mins 42 secs
+ | @ 324 days 11 hours 9 mins 41 secs
+ | @ 324 days 12 hours 9 mins 40 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 45 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1332 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1451 days 20 hours 51 mins 44 secs
+ | @ 1450 days 20 hours 51 mins 44 secs
+ | @ 1449 days 20 hours 51 mins 44 secs
+ | @ 1448 days 20 hours 51 mins 44 secs
+ | @ 1447 days 20 hours 51 mins 44 secs
+ | @ 1446 days 20 hours 51 mins 44 secs
+ | @ 765900 days 20 hours 51 mins 44 secs
+ | @ 695406 days 20 hours 51 mins 44 secs
+ | @ 512785 days 20 hours 51 mins 44 secs
+ | @ 330164 days 20 hours 51 mins 44 secs
+ | @ 111018 days 20 hours 51 mins 44 secs
+ | @ 74494 days 20 hours 51 mins 44 secs
+ | @ 37970 days 20 hours 51 mins 44 secs
+ | @ 1446 days 20 hours 51 mins 44 secs
+ | @ 35078 days 3 hours 8 mins 16 secs
+ | @ 1800 days 20 hours 51 mins 44 secs
+ | @ 1799 days 20 hours 51 mins 44 secs
+ | @ 1798 days 20 hours 51 mins 44 secs
+ | @ 1494 days 20 hours 51 mins 44 secs
+ | @ 1493 days 20 hours 51 mins 44 secs
+ | @ 1492 days 20 hours 51 mins 44 secs
+ | @ 1434 days 20 hours 51 mins 44 secs
+ | @ 1433 days 20 hours 51 mins 44 secs
+ | @ 1129 days 20 hours 51 mins 44 secs
+ | @ 1128 days 20 hours 51 mins 44 secs
+ | @ 398 days 20 hours 51 mins 44 secs
+ | @ 397 days 20 hours 51 mins 44 secs
+ | @ 32 days 20 hours 51 mins 44 secs
+ | @ 31 days 20 hours 51 mins 44 secs
+(63 rows)
+
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index 8a4c719..0a05e37 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -2544,3 +2544,217 @@ select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00';
Tue Jan 17 16:00:00 2017 PST
(1 row)
+-- distance operators
+SELECT '' AS "0", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMPTZ_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+---------------------------------------
+ | @ 11356 days 8 hours
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 58 secs
+ | @ 1453 days 6 hours 27 mins 58.6 secs
+ | @ 1453 days 6 hours 27 mins 58.5 secs
+ | @ 1453 days 6 hours 27 mins 58.4 secs
+ | @ 1493 days
+ | @ 1492 days 20 hours 55 mins 55 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1333 days 7 hours 27 mins 59 secs
+ | @ 231 days 17 hours 19 mins 20 secs
+ | @ 324 days 15 hours 45 mins 59 secs
+ | @ 324 days 19 hours 45 mins 58 secs
+ | @ 324 days 21 hours 45 mins 57 secs
+ | @ 324 days 20 hours 45 mins 56 secs
+ | @ 324 days 22 hours 45 mins 55 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 28 mins
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1453 days 14 hours 27 mins 59 secs
+ | @ 1453 days 14 hours 27 mins 59 secs
+ | @ 1453 days 14 hours 27 mins 59 secs
+ | @ 1453 days 9 hours 27 mins 59 secs
+ | @ 1303 days 10 hours 27 mins 59 secs
+ | @ 1333 days 6 hours 27 mins 59 secs
+ | @ 1453 days 6 hours 27 mins 59 secs
+ | @ 1452 days 6 hours 27 mins 59 secs
+ | @ 1451 days 6 hours 27 mins 59 secs
+ | @ 1450 days 6 hours 27 mins 59 secs
+ | @ 1449 days 6 hours 27 mins 59 secs
+ | @ 1448 days 6 hours 27 mins 59 secs
+ | @ 1447 days 6 hours 27 mins 59 secs
+ | @ 765901 days 6 hours 27 mins 59 secs
+ | @ 695407 days 6 hours 27 mins 59 secs
+ | @ 512786 days 6 hours 27 mins 59 secs
+ | @ 330165 days 6 hours 27 mins 59 secs
+ | @ 111019 days 6 hours 27 mins 59 secs
+ | @ 74495 days 6 hours 27 mins 59 secs
+ | @ 37971 days 6 hours 27 mins 59 secs
+ | @ 1447 days 6 hours 27 mins 59 secs
+ | @ 35077 days 17 hours 32 mins 1 sec
+ | @ 1801 days 6 hours 27 mins 59 secs
+ | @ 1800 days 6 hours 27 mins 59 secs
+ | @ 1799 days 6 hours 27 mins 59 secs
+ | @ 1495 days 6 hours 27 mins 59 secs
+ | @ 1494 days 6 hours 27 mins 59 secs
+ | @ 1493 days 6 hours 27 mins 59 secs
+ | @ 1435 days 6 hours 27 mins 59 secs
+ | @ 1434 days 6 hours 27 mins 59 secs
+ | @ 1130 days 6 hours 27 mins 59 secs
+ | @ 1129 days 6 hours 27 mins 59 secs
+ | @ 399 days 6 hours 27 mins 59 secs
+ | @ 398 days 6 hours 27 mins 59 secs
+ | @ 33 days 6 hours 27 mins 59 secs
+ | @ 32 days 6 hours 27 mins 59 secs
+(64 rows)
+
+SELECT '' AS "0", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMPTZ_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+---------------------------------------
+ | @ 11356 days 9 hours 23 mins 45 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 43 secs
+ | @ 1453 days 7 hours 51 mins 43.6 secs
+ | @ 1453 days 7 hours 51 mins 43.5 secs
+ | @ 1453 days 7 hours 51 mins 43.4 secs
+ | @ 1493 days 1 hour 23 mins 45 secs
+ | @ 1492 days 22 hours 19 mins 40 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1333 days 8 hours 51 mins 44 secs
+ | @ 231 days 15 hours 55 mins 35 secs
+ | @ 324 days 17 hours 9 mins 44 secs
+ | @ 324 days 21 hours 9 mins 43 secs
+ | @ 324 days 23 hours 9 mins 42 secs
+ | @ 324 days 22 hours 9 mins 41 secs
+ | @ 325 days 9 mins 40 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 45 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1453 days 15 hours 51 mins 44 secs
+ | @ 1453 days 15 hours 51 mins 44 secs
+ | @ 1453 days 15 hours 51 mins 44 secs
+ | @ 1453 days 10 hours 51 mins 44 secs
+ | @ 1303 days 11 hours 51 mins 44 secs
+ | @ 1333 days 7 hours 51 mins 44 secs
+ | @ 1453 days 7 hours 51 mins 44 secs
+ | @ 1452 days 7 hours 51 mins 44 secs
+ | @ 1451 days 7 hours 51 mins 44 secs
+ | @ 1450 days 7 hours 51 mins 44 secs
+ | @ 1449 days 7 hours 51 mins 44 secs
+ | @ 1448 days 7 hours 51 mins 44 secs
+ | @ 1447 days 7 hours 51 mins 44 secs
+ | @ 765901 days 7 hours 51 mins 44 secs
+ | @ 695407 days 7 hours 51 mins 44 secs
+ | @ 512786 days 7 hours 51 mins 44 secs
+ | @ 330165 days 7 hours 51 mins 44 secs
+ | @ 111019 days 7 hours 51 mins 44 secs
+ | @ 74495 days 7 hours 51 mins 44 secs
+ | @ 37971 days 7 hours 51 mins 44 secs
+ | @ 1447 days 7 hours 51 mins 44 secs
+ | @ 35077 days 16 hours 8 mins 16 secs
+ | @ 1801 days 7 hours 51 mins 44 secs
+ | @ 1800 days 7 hours 51 mins 44 secs
+ | @ 1799 days 7 hours 51 mins 44 secs
+ | @ 1495 days 7 hours 51 mins 44 secs
+ | @ 1494 days 7 hours 51 mins 44 secs
+ | @ 1493 days 7 hours 51 mins 44 secs
+ | @ 1435 days 7 hours 51 mins 44 secs
+ | @ 1434 days 7 hours 51 mins 44 secs
+ | @ 1130 days 7 hours 51 mins 44 secs
+ | @ 1129 days 7 hours 51 mins 44 secs
+ | @ 399 days 7 hours 51 mins 44 secs
+ | @ 398 days 7 hours 51 mins 44 secs
+ | @ 33 days 7 hours 51 mins 44 secs
+ | @ 32 days 7 hours 51 mins 44 secs
+(64 rows)
+
+SELECT '' AS "0", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMPTZ_TBL;
+ERROR: interval out of range
+SELECT '' AS "63", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);
+ 63 | Distance
+----+----------------------------------------
+ | @ 11355 days 22 hours 23 mins 45 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 43 secs
+ | @ 1452 days 20 hours 51 mins 43.6 secs
+ | @ 1452 days 20 hours 51 mins 43.5 secs
+ | @ 1452 days 20 hours 51 mins 43.4 secs
+ | @ 1492 days 14 hours 23 mins 45 secs
+ | @ 1492 days 11 hours 19 mins 40 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1332 days 21 hours 51 mins 44 secs
+ | @ 232 days 2 hours 55 mins 35 secs
+ | @ 324 days 6 hours 9 mins 44 secs
+ | @ 324 days 10 hours 9 mins 43 secs
+ | @ 324 days 12 hours 9 mins 42 secs
+ | @ 324 days 11 hours 9 mins 41 secs
+ | @ 324 days 13 hours 9 mins 40 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 45 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1453 days 4 hours 51 mins 44 secs
+ | @ 1453 days 4 hours 51 mins 44 secs
+ | @ 1453 days 4 hours 51 mins 44 secs
+ | @ 1452 days 23 hours 51 mins 44 secs
+ | @ 1303 days 51 mins 44 secs
+ | @ 1332 days 20 hours 51 mins 44 secs
+ | @ 1452 days 20 hours 51 mins 44 secs
+ | @ 1451 days 20 hours 51 mins 44 secs
+ | @ 1450 days 20 hours 51 mins 44 secs
+ | @ 1449 days 20 hours 51 mins 44 secs
+ | @ 1448 days 20 hours 51 mins 44 secs
+ | @ 1447 days 20 hours 51 mins 44 secs
+ | @ 1446 days 20 hours 51 mins 44 secs
+ | @ 765900 days 20 hours 51 mins 44 secs
+ | @ 695406 days 20 hours 51 mins 44 secs
+ | @ 512785 days 20 hours 51 mins 44 secs
+ | @ 330164 days 20 hours 51 mins 44 secs
+ | @ 111018 days 20 hours 51 mins 44 secs
+ | @ 74494 days 20 hours 51 mins 44 secs
+ | @ 37970 days 20 hours 51 mins 44 secs
+ | @ 1446 days 20 hours 51 mins 44 secs
+ | @ 35078 days 3 hours 8 mins 16 secs
+ | @ 1800 days 20 hours 51 mins 44 secs
+ | @ 1799 days 20 hours 51 mins 44 secs
+ | @ 1798 days 20 hours 51 mins 44 secs
+ | @ 1494 days 20 hours 51 mins 44 secs
+ | @ 1493 days 20 hours 51 mins 44 secs
+ | @ 1492 days 20 hours 51 mins 44 secs
+ | @ 1434 days 20 hours 51 mins 44 secs
+ | @ 1433 days 20 hours 51 mins 44 secs
+ | @ 1129 days 20 hours 51 mins 44 secs
+ | @ 1128 days 20 hours 51 mins 44 secs
+ | @ 398 days 20 hours 51 mins 44 secs
+ | @ 397 days 20 hours 51 mins 44 secs
+ | @ 32 days 20 hours 51 mins 44 secs
+ | @ 31 days 20 hours 51 mins 44 secs
+(64 rows)
+
diff --git a/src/test/regress/sql/date.sql b/src/test/regress/sql/date.sql
index 22f80f2..24be476 100644
--- a/src/test/regress/sql/date.sql
+++ b/src/test/regress/sql/date.sql
@@ -346,3 +346,8 @@ select make_date(2013, 13, 1);
select make_date(2013, 11, -1);
select make_time(10, 55, 100.1);
select make_time(24, 0, 2.1);
+
+-- distance operators
+SELECT '' AS "Fifteen", f1 <-> date '2001-02-03' AS "Distance" FROM DATE_TBL;
+SELECT '' AS "Fifteen", f1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM DATE_TBL;
+SELECT '' AS "Fifteen", f1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM DATE_TBL;
diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql
index 646027f..35b5942 100644
--- a/src/test/regress/sql/float4.sql
+++ b/src/test/regress/sql/float4.sql
@@ -87,6 +87,9 @@ UPDATE FLOAT4_TBL
SELECT '' AS five, * FROM FLOAT4_TBL;
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3' AS dist FROM FLOAT4_TBL f;
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float8 AS dist FROM FLOAT4_TBL f;
+
-- test edge-case coercions to integer
SELECT '32767.4'::float4::int2;
SELECT '32767.6'::float4::int2;
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index a333218..7fe9bca 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -131,6 +131,9 @@ SELECT ||/ float8 '27' AS three;
SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f;
+-- distance
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float8 AS dist FROM FLOAT8_TBL f;
+SELECT '' AS five, f.f1, f.f1 <-> '1004.3'::float4 AS dist FROM FLOAT8_TBL f;
SELECT '' AS five, * FROM FLOAT8_TBL;
diff --git a/src/test/regress/sql/int2.sql b/src/test/regress/sql/int2.sql
index 7dbafb6..16dd5d8 100644
--- a/src/test/regress/sql/int2.sql
+++ b/src/test/regress/sql/int2.sql
@@ -84,6 +84,16 @@ SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT2_TBL i;
SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i;
+-- distance
+SELECT '' AS five, i.f1, i.f1 <-> int2 '2' AS x FROM INT2_TBL i;
+
+SELECT '' AS four, i.f1, i.f1 <-> int2 '2' AS x FROM INT2_TBL i
+WHERE f1 > -32767;
+
+SELECT '' AS five, i.f1, i.f1 <-> int4 '2' AS x FROM INT2_TBL i;
+
+SELECT '' AS five, i.f1, i.f1 <-> int8 '2' AS x FROM INT2_TBL i;
+
-- corner cases
SELECT (-1::int2<<15)::text;
SELECT ((-1::int2<<15)+1::int2)::text;
diff --git a/src/test/regress/sql/int4.sql b/src/test/regress/sql/int4.sql
index f014cb2..cff32946 100644
--- a/src/test/regress/sql/int4.sql
+++ b/src/test/regress/sql/int4.sql
@@ -93,6 +93,16 @@ SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i;
SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i;
+SELECT '' AS five, i.f1, i.f1 <-> int2 '2' AS x FROM INT4_TBL i;
+
+SELECT '' AS four, i.f1, i.f1 <-> int2 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+
+SELECT '' AS four, i.f1, i.f1 <-> int4 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+
+SELECT '' AS five, i.f1, i.f1 <-> int8 '2' AS x FROM INT4_TBL i;
+
--
-- more complex expressions
--
diff --git a/src/test/regress/sql/int8.sql b/src/test/regress/sql/int8.sql
index e890452..d7f5bde 100644
--- a/src/test/regress/sql/int8.sql
+++ b/src/test/regress/sql/int8.sql
@@ -89,6 +89,11 @@ SELECT q1 + 42::int2 AS "8plus2", q1 - 42::int2 AS "8minus2", q1 * 42::int2 AS "
-- int2 op int8
SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 AS "2mul8", 246::int2 / q1 AS "2div8" FROM INT8_TBL;
+-- distance
+SELECT '' AS five, q2, q2 <-> int2 '123' AS dist FROM INT8_TBL i;
+SELECT '' AS five, q2, q2 <-> int4 '123' AS dist FROM INT8_TBL i;
+SELECT '' AS five, q2, q2 <-> int8 '123' AS dist FROM INT8_TBL i;
+
SELECT q2, abs(q2) FROM INT8_TBL;
SELECT min(q1), min(q2) FROM INT8_TBL;
SELECT max(q1), max(q2) FROM INT8_TBL;
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql
index bc5537d..d51c866 100644
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -59,6 +59,8 @@ SELECT '' AS fortyfive, r1.*, r2.*
WHERE r1.f1 > r2.f1
ORDER BY r1.f1, r2.f1;
+SELECT '' AS ten, f1 <-> interval '@ 2 day 3 hours' FROM INTERVAL_TBL;
+
-- Test intervals that are large enough to overflow 64 bits in comparisons
CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval);
INSERT INTO INTERVAL_TBL_OF (f1) VALUES
diff --git a/src/test/regress/sql/money.sql b/src/test/regress/sql/money.sql
index 37b9ecc..8428d59 100644
--- a/src/test/regress/sql/money.sql
+++ b/src/test/regress/sql/money.sql
@@ -25,6 +25,7 @@ SELECT m / 2::float8 FROM money_data;
SELECT m * 2::float4 FROM money_data;
SELECT 2::float4 * m FROM money_data;
SELECT m / 2::float4 FROM money_data;
+SELECT m <-> '$123.45' FROM money_data;
-- All true
SELECT m = '$123.00' FROM money_data;
diff --git a/src/test/regress/sql/oid.sql b/src/test/regress/sql/oid.sql
index 4a09689..9f54f92 100644
--- a/src/test/regress/sql/oid.sql
+++ b/src/test/regress/sql/oid.sql
@@ -40,4 +40,6 @@ SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 > '1234';
+SELECT '' AS eight, f1, f1 <-> oid '123' FROM OID_TBL;
+
DROP TABLE OID_TBL;
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index e2014fc..959928b 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -818,7 +818,7 @@ WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND
ao.amoprighttype = ap.amprocrighttype AND
ap.amprocnum = 1 AND
(pp.provolatile != po.provolatile OR
- pp.proleakproof != po.proleakproof)
+ (NOT pp.proleakproof AND po.proleakproof))
ORDER BY 1;
diff --git a/src/test/regress/sql/time.sql b/src/test/regress/sql/time.sql
index 99a1562..31f0330 100644
--- a/src/test/regress/sql/time.sql
+++ b/src/test/regress/sql/time.sql
@@ -40,3 +40,6 @@ SELECT f1 AS "Eight" FROM TIME_TBL WHERE f1 >= '00:00';
-- where we do mixed-type arithmetic. - thomas 2000-12-02
SELECT f1 + time '00:01' AS "Illegal" FROM TIME_TBL;
+
+-- distance
+SELECT f1 AS "Ten", f1 <-> time '01:23:45' AS "Distance" FROM TIME_TBL;
diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql
index b7957cb..5d023dd 100644
--- a/src/test/regress/sql/timestamp.sql
+++ b/src/test/regress/sql/timestamp.sql
@@ -230,3 +230,11 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
-- timestamp numeric fields constructor
SELECT make_timestamp(2014,12,28,6,30,45.887);
+
+-- distance operators
+SELECT '' AS "0", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMP_TBL;
+SELECT '' AS "63", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
+SELECT '' AS "0", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMP_TBL;
+SELECT '' AS "63", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
+SELECT '' AS "0", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMP_TBL;
+SELECT '' AS "63", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMP_TBL WHERE isfinite(d1);
diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql
index c3bd46c..7f0525d 100644
--- a/src/test/regress/sql/timestamptz.sql
+++ b/src/test/regress/sql/timestamptz.sql
@@ -464,3 +464,11 @@ insert into tmptz values ('2017-01-18 00:00+00');
explain (costs off)
select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00';
select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00';
+
+-- distance operators
+SELECT '' AS "0", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMPTZ_TBL;
+SELECT '' AS "63", d1 <-> date '2001-02-03' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);
+SELECT '' AS "0", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMPTZ_TBL;
+SELECT '' AS "63", d1 <-> timestamp '2001-02-03 01:23:45' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);
+SELECT '' AS "0", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMPTZ_TBL;
+SELECT '' AS "63", d1 <-> timestamptz '2001-02-03 01:23:45+03' AS "Distance" FROM TIMESTAMPTZ_TBL WHERE isfinite(d1);