From 181ca96e7a730ba35e973d3361422e6d8a460f88 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sat, 10 Aug 2002 20:38:29 +0000
Subject: [PATCH] August 6, 2002    1. Reworked patch from Andrey Oktyabrski
 (ano@spider.ru) with       functions: icount, sort, sort_asc, uniq, idx,
 subarray       operations: #, +, -, |, &

FUNCTIONS:

  int   icount(int[]) - the number of elements in intarray
  int[] sort(int[], 'asc' | 'desc') - sort intarray
  int[] sort(int[]) - sort in ascending order
  int[] sort_asc(int[]),sort_desc(int[]) - shortcuts for sort
  int[] uniq(int[]) - returns unique elements
  int   idx(int[], int item) - returns index of first intarray matching element
                               to item, or '0' if matching failed.
  int[] subarray(int[],int START [, int LEN]) - returns part of intarray
                               starting from element number START (from 1)
                               and length LEN.
OPERATIONS:

  int[] && int[]  - overlap - returns TRUE if arrays has at least one common elements.
  int[] @  int[]  - contains - returns TRUE if left array contains right array
  int[] ~ int[]   - contained - returns TRUE if left array is contained in right array
  # int[]         - return the number of elements in array
  int[] + int     - push element to array ( add to end of array)
  int[] + int[]   - merge of arrays (right array added to the end of left one)
  int[] - int     - remove entries matched by right argument from array
  int[] - int[]   - remove left array from right
  int[] | int     - returns intarray - union of arguments
  int[] | int[]   - returns intarray as a union of two arrays
  int[] & int[]   - returns intersection of arrays

Oleg Bartunov
---
 contrib/intarray/README.intarray   |  34 +++-
 contrib/intarray/_int.c            | 300 +++++++++++++++++++++++++++++
 contrib/intarray/_int.sql.in       |  75 ++++++++
 contrib/intarray/expected/_int.out | 138 +++++++++++++
 contrib/intarray/sql/_int.sql      |  26 +++
 5 files changed, 572 insertions(+), 1 deletion(-)

diff --git a/contrib/intarray/README.intarray b/contrib/intarray/README.intarray
index f0138a14842..bac191e65d3 100644
--- a/contrib/intarray/README.intarray
+++ b/contrib/intarray/README.intarray
@@ -8,10 +8,42 @@ signature with length of 4096 bits to represent sets).
 
 All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov
 (oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
-for additional information.
+for additional information. Andrey Oktyabrski has done a great work on 
+adding new functions and operations.
+
+
+FUNCTIONS:
+
+  int   icount(int[]) - the number of elements in intarray
+  int[] sort(int[], 'asc' | 'desc') - sort intarray
+  int[] sort(int[]) - sort in ascending order
+  int[] sort_asc(int[]),sort_desc(int[]) - shortcuts for sort 
+  int[] uniq(int[]) - returns unique elements
+  int   idx(int[], int item) - returns index of first intarray matching element to item, or
+                              '0' if matching failed.
+  int[] subarray(int[],int START [, int LEN]) - returns part of intarray starting from
+                                                element number START (from 1) and length LEN. 
+
+OPERATIONS:
+
+  int[] && int[]  - overlap - returns TRUE if arrays has at least one common elements.
+  int[] @  int[]  - contains - returns TRUE if left array contains right array
+  int[] ~ int[]   - contained - returns TRUE if left array is contained in right array
+  # int[]         - return the number of elements in array
+  int[] + int     - push element to array ( add to end of array)
+  int[] + int[]   - merge of arrays (right array added to the end of left one)
+  int[] - int     - remove entries matched by right argument from array
+  int[] - int[]   - remove left array from right
+  int[] | int     - returns intarray - union of arguments
+  int[] | int[]   - returns intarray as a union of two arrays
+  int[] & int[]   - returns intersection of arrays
 
 CHANGES:
 
+August 6, 2002
+   1. Reworked patch from Andrey Oktyabrski (ano@spider.ru) with
+      functions: icount, sort, sort_asc, uniq, idx, subarray
+      operations: #, +, -, |, &
 October 1, 2001
    1. Change search method in array to binary
 September 28, 2001
diff --git a/contrib/intarray/_int.c b/contrib/intarray/_int.c
index d956543af5f..1c0de0bce80 100644
--- a/contrib/intarray/_int.c
+++ b/contrib/intarray/_int.c
@@ -2217,3 +2217,303 @@ querytree(PG_FUNCTION_ARGS) {
 
 	PG_RETURN_POINTER( res );
 }
+
+/*
+** Additional array functions
+*/
+static int32 intarray_match_first(ArrayType *a, int32 elem);
+static ArrayType *intarray_add_elem(ArrayType *a, int32 elem);
+static ArrayType *intarray_concat_arrays(ArrayType *a, ArrayType *b);
+static ArrayType *int_to_intset(int32 elem);
+
+PG_FUNCTION_INFO_V1( intset );
+PG_FUNCTION_INFO_V1( icount );
+PG_FUNCTION_INFO_V1( sort );
+PG_FUNCTION_INFO_V1( sort_asc );
+PG_FUNCTION_INFO_V1( sort_desc );
+PG_FUNCTION_INFO_V1( uniq );
+PG_FUNCTION_INFO_V1( idx );
+PG_FUNCTION_INFO_V1( subarray );
+PG_FUNCTION_INFO_V1( intarray_push_elem );
+PG_FUNCTION_INFO_V1( intarray_push_array );
+PG_FUNCTION_INFO_V1( intarray_del_elem );
+PG_FUNCTION_INFO_V1( intset_union_elem );
+PG_FUNCTION_INFO_V1( intset_subtract );
+Datum intset(PG_FUNCTION_ARGS);
+Datum icount(PG_FUNCTION_ARGS);
+Datum sort(PG_FUNCTION_ARGS);
+Datum sort_asc(PG_FUNCTION_ARGS);
+Datum sort_desc(PG_FUNCTION_ARGS);
+Datum uniq(PG_FUNCTION_ARGS);
+Datum idx(PG_FUNCTION_ARGS);
+Datum subarray(PG_FUNCTION_ARGS);
+Datum intarray_push_elem(PG_FUNCTION_ARGS);
+Datum intarray_push_array(PG_FUNCTION_ARGS);
+Datum intarray_del_elem(PG_FUNCTION_ARGS);
+Datum intset_union_elem(PG_FUNCTION_ARGS);
+Datum intset_subtract(PG_FUNCTION_ARGS);
+
+static int32
+intarray_match_first(ArrayType *a, int32 elem) {
+	int32 *aa, c, i;
+	c  = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	aa = ARRPTR(a);
+	for (i = 0; i < c; i++)
+		if (aa[i] == elem) return (i + 1);
+	return 0;
+}
+
+static ArrayType *
+intarray_add_elem(ArrayType *a, int32 elem) {
+	ArrayType *result;
+	int32 *r;
+	int32 c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	result = new_intArrayType(c + 1);
+	r = ARRPTR(result);
+	if (c > 0) memcpy(r, ARRPTR(a), c * sizeof(int32));
+	r[c] = elem;
+	return result;
+}
+
+static ArrayType *
+intarray_concat_arrays(ArrayType *a, ArrayType *b) {
+	ArrayType *result;
+	int32 ac = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	int32 bc = (ARRISVOID(b)) ? 0 : ARRNELEMS(b);
+	result = new_intArrayType(ac+bc);
+	if ( ac )
+		memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
+	if ( bc )
+		memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
+	return result;
+}
+
+static ArrayType *
+int_to_intset(int32 n) {
+	ArrayType *result;
+	int32 *aa;
+	result = new_intArrayType(1);
+	aa = ARRPTR(result);
+	aa[0] = n;
+	return result;
+}
+
+static int
+compASC(const void *a, const void *b) {
+	if ( *(int4*)a == *(int4*)b ) return 0;
+	return ( *(int4*)a > *(int4*)b ) ? 1 : -1;
+}
+
+static int
+compDESC(const void *a, const void *b) {
+	if ( *(int4*)a == *(int4*)b ) return 0;
+	return ( *(int4*)a < *(int4*)b ) ? 1 : -1;
+}
+
+#define QSORT(a, direction) 					\
+if (ARRNELEMS(a) > 1)						\
+	qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4), 	\
+		(direction) ? compASC : compDESC )
+
+#define UNIX_UNIQ(a) a = resize_intArrayType(a, unix_uniq(ARRPTR(a), ARRNELEMS(a)))
+
+static int32
+unix_uniq(int32 *array, int32 count) {
+	register int32 i, k = 0;
+	for (i = 1; i < count; i++)
+		if (array[k] != array[i]) {
+			k++;
+			if (i > k) array[k] = array[i];
+		}
+	return (k+1);
+}
+
+Datum
+intset(PG_FUNCTION_ARGS) {
+  PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
+}
+
+Datum
+icount(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	int32 count = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	PG_FREE_IF_COPY(a, 0);
+	PG_RETURN_INT32(count);
+}
+
+Datum
+sort(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	text *dirstr = ( fcinfo->nargs==2 ) ? PG_GETARG_TEXT_P(1) : NULL;
+	int32 dc = ( dirstr ) ? VARSIZE(dirstr)-VARHDRSZ : 0;
+	char *d = ( dirstr ) ? VARDATA(dirstr) : NULL;
+	int dir = -1;
+	if (ARRISVOID(a) || ARRNELEMS(a) < 2) PG_RETURN_POINTER(a);
+
+	if (dirstr==NULL || (dc == 3
+	 && (d[0] == 'A' || d[0] == 'a')
+	 && (d[1] == 'S' || d[1] == 's')
+	 && (d[2] == 'C' || d[2] == 'c')))
+		dir = 1;
+	else if (dc == 4
+	 && (d[0] == 'D' || d[0] == 'd')
+	 && (d[1] == 'E' || d[1] == 'e')
+	 && (d[2] == 'S' || d[2] == 's')
+	 && (d[3] == 'C' || d[3] == 'c'))
+		dir = 0;
+	if (dir == -1)
+		elog(ERROR, "Invalid second parameter in function sort. It must be 'ASC' or 'DESC'.");
+	QSORT(a, dir);
+	PG_RETURN_POINTER(a);
+}
+
+Datum
+sort_asc(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	if (ARRISVOID(a)) PG_RETURN_POINTER(a);
+	QSORT(a, 1);
+	PG_RETURN_POINTER(a);
+}
+
+Datum
+sort_desc(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	if (ARRISVOID(a)) PG_RETURN_POINTER(a);
+	QSORT(a, 0);
+	PG_RETURN_POINTER(a);
+}
+
+Datum
+uniq(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	if (ARRISVOID(a) || ARRNELEMS(a) < 2) PG_RETURN_POINTER(a);
+	UNIX_UNIQ(a);
+	PG_RETURN_POINTER(a);
+}
+
+Datum
+idx(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	int32 result = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	if (result) result = intarray_match_first(a, PG_GETARG_INT32(1));
+	PG_FREE_IF_COPY(a, 0);
+	PG_RETURN_INT32(result);
+}
+
+Datum
+subarray(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	ArrayType *result;
+	int32 start = ( PG_GETARG_INT32(1) > 0 ) ? PG_GETARG_INT32(1)-1 : PG_GETARG_INT32(1);
+	int32 len = ( fcinfo->nargs==3 ) ? PG_GETARG_INT32(2) : 0;
+	int32 end = 0;
+	int32 c;
+
+	if ( ARRISVOID(a) ) {
+		PG_FREE_IF_COPY(a, 0);
+		PG_RETURN_POINTER( new_intArrayType(0) );
+	}
+
+	c = ARRNELEMS(a);
+	
+	if ( start < 0 )
+		start = c + start;
+
+	if ( len < 0 )
+		end = c + len;
+	else if ( len == 0 )
+		end = c;
+	else
+		end = start + len;
+
+	if ( end > c )
+		end = c; 
+
+	if ( start < 0 )
+		start = 0;
+
+	if ( start >= end || end <= 0 ) { 
+		PG_FREE_IF_COPY(a, 0);
+		PG_RETURN_POINTER( new_intArrayType(0) );
+	}
+
+
+	result = new_intArrayType(end-start);
+	if (end-start > 0) 
+		memcpy(ARRPTR(result), ARRPTR(a) + start, (end-start) * sizeof(int32));
+	PG_FREE_IF_COPY(a, 0);
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+intarray_push_elem(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	ArrayType *result;
+	result = intarray_add_elem(a, PG_GETARG_INT32(1));
+	PG_FREE_IF_COPY(a, 0);
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+intarray_push_array(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	ArrayType *b = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
+	ArrayType *result;
+	result = intarray_concat_arrays(a, b);
+	PG_FREE_IF_COPY(a, 0);
+	PG_FREE_IF_COPY(b, 1);
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+intarray_del_elem(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	int32 c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	int32 *aa = ARRPTR(a);
+	int32 n = 0, i;
+	int32 elem = PG_GETARG_INT32(1);
+	for (i = 0; i < c; i++)
+		if (aa[i] != elem) {
+			if (i > n) aa[n++] = aa[i];
+			else n++;
+		}
+	if (c > 0) a = resize_intArrayType(a, n);
+	PG_RETURN_POINTER(a);
+}
+
+Datum
+intset_union_elem(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
+	ArrayType *result;
+	result = intarray_add_elem(a, PG_GETARG_INT32(1));
+	PG_FREE_IF_COPY(a, 0);
+	QSORT(result, 1);
+	UNIX_UNIQ(result);
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+intset_subtract(PG_FUNCTION_ARGS) {
+	ArrayType *a = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+	ArrayType *b = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
+	ArrayType *result;
+	int32 ca = ARRISVOID(a);
+	int32 cb = ARRISVOID(b);
+	int32 *aa, *bb, *r;
+	int32 n = 0, i = 0, k = 0;
+	QSORT(a, 1); UNIX_UNIQ(a); ca = ARRNELEMS(a);
+	QSORT(b, 1); UNIX_UNIQ(b); cb = ARRNELEMS(b);
+	result = new_intArrayType(ca);
+	aa = ARRPTR(a);
+	bb = ARRPTR(b);
+	r = ARRPTR(result);
+	while (i < ca) {
+		if (k == cb || aa[i] < bb[k]) r[n++] = aa[i++];
+		else if (aa[i] == bb[k]) { i++; k++; }
+		else k++;
+	}
+	result = resize_intArrayType(result, n);
+	pfree(a); pfree(b);
+	PG_RETURN_POINTER(result);
+}
+
diff --git a/contrib/intarray/_int.sql.in b/contrib/intarray/_int.sql.in
index 24a87cb0356..fe1a6f9d389 100644
--- a/contrib/intarray/_int.sql.in
+++ b/contrib/intarray/_int.sql.in
@@ -123,6 +123,81 @@ CREATE OPERATOR ~ (
    COMMUTATOR = '@', RESTRICT = contsel, JOIN = contjoinsel
 );
 
+--------------
+CREATE FUNCTION intset(int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION icount(_int4) RETURNS int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR # (
+   RIGHTARG = _int4, PROCEDURE = icount
+);
+
+CREATE FUNCTION sort(_int4, text) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION sort(_int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION sort_asc(_int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION sort_desc(_int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION uniq(_int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION idx(_int4, int4) RETURNS int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR # (
+   LEFTARG = _int4, RIGHTARG = int4, PROCEDURE = idx
+);
+
+CREATE FUNCTION subarray(_int4, int4, int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION subarray(_int4, int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+
+CREATE FUNCTION intarray_push_elem(_int4, int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR + (
+   LEFTARG = _int4, RIGHTARG = int4, PROCEDURE = intarray_push_elem
+);
+
+CREATE FUNCTION intarray_push_array(_int4, _int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR + (
+   LEFTARG = _int4, RIGHTARG = _int4, COMMUTATOR = +, PROCEDURE = intarray_push_array
+);
+
+CREATE FUNCTION intarray_del_elem(_int4, int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR - (
+   LEFTARG = _int4, RIGHTARG = int4, PROCEDURE = intarray_del_elem
+);
+
+CREATE FUNCTION intset_union_elem(_int4, int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR | (
+   LEFTARG = _int4, RIGHTARG = int4, PROCEDURE = intset_union_elem
+);
+
+CREATE OPERATOR | (
+   LEFTARG = _int4, RIGHTARG = _int4, COMMUTATOR = |, PROCEDURE = _int_union
+);
+
+CREATE FUNCTION intset_subtract(_int4, _int4) RETURNS _int4
+	AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict, isCachable);
+CREATE OPERATOR - (
+   LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = intset_subtract
+);
+
+CREATE OPERATOR & (
+   LEFTARG = _int4, RIGHTARG = _int4, COMMUTATOR = &, PROCEDURE = _int_inter
+);
+--------------
 
 -- define the GiST support methods
 CREATE FUNCTION g_int_consistent(opaque,_int4,int4) RETURNS bool
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index d1b440f5a9b..87298630be4 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -3,6 +3,144 @@
 -- does not depend on contents of seg.sql.
 --
 \set ECHO none
+select intset(1234);
+ intset 
+--------
+ {1234}
+(1 row)
+
+select icount('{1234234,234234}');
+ icount 
+--------
+      2
+(1 row)
+
+select sort('{1234234,-30,234234}');
+         sort         
+----------------------
+ {-30,234234,1234234}
+(1 row)
+
+select sort('{1234234,-30,234234}','asc');
+         sort         
+----------------------
+ {-30,234234,1234234}
+(1 row)
+
+select sort('{1234234,-30,234234}','desc');
+         sort         
+----------------------
+ {1234234,234234,-30}
+(1 row)
+
+select sort_asc('{1234234,-30,234234}');
+       sort_asc       
+----------------------
+ {-30,234234,1234234}
+(1 row)
+
+select sort_desc('{1234234,-30,234234}');
+      sort_desc       
+----------------------
+ {1234234,234234,-30}
+(1 row)
+
+select uniq('{1234234,-30,-30,234234,-30}');
+           uniq           
+--------------------------
+ {1234234,-30,234234,-30}
+(1 row)
+
+select uniq(sort_asc('{1234234,-30,-30,234234,-30}'));
+         uniq         
+----------------------
+ {-30,234234,1234234}
+(1 row)
+
+select idx('{1234234,-30,-30,234234,-30}',-30);
+ idx 
+-----
+   2
+(1 row)
+
+select subarray('{1234234,-30,-30,234234,-30}',2,3);
+     subarray     
+------------------
+ {-30,-30,234234}
+(1 row)
+
+select subarray('{1234234,-30,-30,234234,-30}',-1,1);
+ subarray 
+----------
+ {-30}
+(1 row)
+
+select subarray('{1234234,-30,-30,234234,-30}',0,-1);
+         subarray         
+--------------------------
+ {1234234,-30,-30,234234}
+(1 row)
+
+select #'{1234234,234234}'::int[];
+ ?column? 
+----------
+        2
+(1 row)
+
+select '{123,623,445}'::int[] + 1245;
+      ?column?      
+--------------------
+ {123,623,445,1245}
+(1 row)
+
+select '{123,623,445}'::int[] + 445;
+     ?column?      
+-------------------
+ {123,623,445,445}
+(1 row)
+
+select '{123,623,445}'::int[] + '{1245,87,445}';
+         ?column?          
+---------------------------
+ {123,623,445,1245,87,445}
+(1 row)
+
+select '{123,623,445}'::int[] - 623;
+ ?column?  
+-----------
+ {123,445}
+(1 row)
+
+select '{123,623,445}'::int[] - '{1623,623}';
+ ?column?  
+-----------
+ {123,445}
+(1 row)
+
+select '{123,623,445}'::int[] | 623;
+   ?column?    
+---------------
+ {123,445,623}
+(1 row)
+
+select '{123,623,445}'::int[] | 1623;
+      ?column?      
+--------------------
+ {123,445,623,1623}
+(1 row)
+
+select '{123,623,445}'::int[] | '{1623,623}';
+      ?column?      
+--------------------
+ {123,445,623,1623}
+(1 row)
+
+select '{123,623,445}'::int[] & '{1623,623}';
+ ?column? 
+----------
+ {623}
+(1 row)
+
 --test query_int
 select '1'::query_int;
  query_int 
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 52313ef7a17..2b0b0d10194 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -6,6 +6,32 @@
 \i _int.sql
 \set ECHO all
 
+select intset(1234);
+select icount('{1234234,234234}');
+select sort('{1234234,-30,234234}');
+select sort('{1234234,-30,234234}','asc');
+select sort('{1234234,-30,234234}','desc');
+select sort_asc('{1234234,-30,234234}');
+select sort_desc('{1234234,-30,234234}');
+select uniq('{1234234,-30,-30,234234,-30}');
+select uniq(sort_asc('{1234234,-30,-30,234234,-30}'));
+select idx('{1234234,-30,-30,234234,-30}',-30);
+select subarray('{1234234,-30,-30,234234,-30}',2,3);
+select subarray('{1234234,-30,-30,234234,-30}',-1,1);
+select subarray('{1234234,-30,-30,234234,-30}',0,-1);
+
+select #'{1234234,234234}'::int[];
+select '{123,623,445}'::int[] + 1245;
+select '{123,623,445}'::int[] + 445;
+select '{123,623,445}'::int[] + '{1245,87,445}';
+select '{123,623,445}'::int[] - 623;
+select '{123,623,445}'::int[] - '{1623,623}';
+select '{123,623,445}'::int[] | 623;
+select '{123,623,445}'::int[] | 1623;
+select '{123,623,445}'::int[] | '{1623,623}';
+select '{123,623,445}'::int[] & '{1623,623}';
+
+
 --test query_int
 select '1'::query_int;
 select ' 1'::query_int;
-- 
GitLab