diff --git a/Makefile b/Makefile index 38cbd7a..5aea88c 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ OBJS = anyarray.o anyarray_util.o anyarray_guc.o \ anyarray_gist.o anyarray_gin.o EXTENSION = anyarray -DATA = anyarray--1.0.sql +DATA = anyarray--1.0.sql anyarray--1.0.sql anyarray--1.0--1.1.sql PGFILEDESC = "anyarray - functions and operators for one-dimensional arrays" REGRESS = init anyarray \ diff --git a/README.md b/README.md new file mode 100644 index 0000000..b91272c --- /dev/null +++ b/README.md @@ -0,0 +1,252 @@ +AnyArray – 1-D anyarray functionality for PostgreSQL +============================================== + +Introduction +------------ + +AnyArray is a PostgreSQL extension which implements 1-D anyarray +functionality. + + +Authors +------- + + * Teodor Sigaev , Postgres Professional, Moscow, Russia + * Oleg Bartunov , Postgres Professional, Moscow, Russia + +Availability +------------ + +AnyArray is released as an extension and not available in default PostgreSQL +installation. It is available from +[github](https://github.com/postgrespro/anyarray) +under the same license as +[PostgreSQL](http://www.postgresql.org/about/licence/) +and supports PostgreSQL 9.1+. + +Installation +------------ + +Before build and install AnyArray you should ensure following: + + * PostgreSQL version is 9.1 or higher. + * You have development package of PostgreSQL installed or you built + PostgreSQL from source. + * Your PATH variable is configured so that pg\_config command available. + +Typical installation procedure may look like this: + + $ git clone https://github.com/postgrespro/anyarray.git + $ cd anyarray + $ make USE_PGXS=1 + $ sudo make USE_PGXS=1 install + $ make USE_PGXS=1 installcheck + $ psql DB -c "CREATE EXTENSION anyarray;" + +Usage +----- + +### Anyarray functions + +|Function|Description|Examples| +|--------|-----------|--------| +|`anyset(int)` → `int[1]`||`anyset(1234)` → `ARRAY[1234]`| +|`icount(anyarray)`→`int`|Returns the length of anyarray. icount() returns 0 for empty arrays.|`icount( '{1234234, 0234234}'::int[] )` → `2`| +|`sort(anyarray [, 'asc'\|'desc'])`→ `anyarray`|Returns the anyarray sorted in an ascending (default) or descending order. |`sort( '{1234234, -30, 0234234}'::int[],'desc')` → `{1234234, 234234, -30}`| +|`sort_asc(anyarray)`→ `anyarray`|Returns the anyarray sorted in an ascending order. |`sort_asc( '{1234234,-30, 0234234}'::int[])` → `{-30,234234,1234234}`| +|`sort_desc(anyarray)`→ `anyarray`|Returns the anyarray sorted in a descending order. |`sort( '{1234234, -30, 0234234}'::int[],'desc' )` → `{1234234,234234,-30}`| +|`uniq(anyarray)`→ `anyarray`|Returns anyarray where consequent repeating elements replaced by one element. If you need to remove all repeating elements in array, you can sort array and apply uniq() function. |`uniq( '{1234234, -30, -30, 0234234, -30}'::int[])` → `{1234234, -30, 234234, -30}` , `uniq( sort_asc( '{1234234, -30, -30, 0234234, -30}'::int[] ) )` → `{-30,234234,1234234}`| +|`uniq_d(anyarray)`→ `anyarray`|Returns only consequent repeating elements. If you need to return all repeating elements, you can sort array and apply uniq_d() function |`uniq_d( '{1234234, -30, -30, 0234234, -30, 0234234}'::int[] )` → `{-30}`, `uniq_d( sort_asc('{1234234, -30,-30, 0234234, -30, 0234234}'::int[] ) )` → `{-30,234234}` | +|`idx(anyarray, searchelement)`→ `int`|Returns the position of the searchelement first occurance in the array |`idx( '{1234234,-30,-30,0234234,-30}'::int[], -30 )` → `2`| +|`subarray(anyarray, start int, length int)`→ `anyarray`|Returns the subarray from original array. If the start position value is negative, it is counted from the end of the original array (-1 means last element, -2 means element before last etc.)|`subarray( '{1234234, -30, -30, 0234234, -30}'::int[],2,3 )` → `{-30, -30, 234234}` , `subarray( '{1234234, -30, -30, 0234234, -30}'::int[], -1, 1 )` → `{-30}`, `subarray( '{1234234, -30, -30, 0234234, -30}'::int[], 0, -1 )` → `{1234234, -30, -30, 234234}`| + + +### Anyarray operators + +|Operator|Description|Examples| +|--------|-----------|--------| +|`#anyarray` → `int`|Returns the length of anyarray. |`#'{1234234,0234234}'::int[]` → `2`| +|`anyarray + anyarray`→ `anyarray`|Returns the union of arrays |`'{123,623,445}'::int[] + 1245` → `{123,623,445,1245}` , `'{123,623,445}'::int[] + '{1245,87,445}'` → `{123,623,445,1245,87,445}` | +|`anyarray - anyarray`→ `anyarray`|Returns the substraction of left array and right array |`'{123,623,445}'::int[] - 623` → `{123,445}`, `'{123,623,445}'::int[] - '{1623,623}'::int[]` `{123,445}`| +|`anyarray \| anyarray`→ `anyarray`|Returns the union of array, repeating elements are excluded from resulting array.|`'{123,623,445}'::int[]` \| `{1623,623}'::int[]` → `{123,445,623,1623}`| +|`anyarray & anyarray`→ `anyarray`|Returns arrays intersection.|`'{1,3,1}'::int[] & '{1,2}'` → `{1}`| + + +### Anyarray operator class strategies + + +|Operator|GIST and GIN Strategy num|Description| +|--------|-------------------------|-----------| +|`anyarray` && `anyarray`|RTOverlapStrategyNumber 3|Overlapped| +|`anyarray` = `anyarray`|RTSameStrategyNumber 6|Same| +|`anyarray` @> `anyarray`|RTContainsStrategyNumber 7|Contains| +|`anyarray` <@ `anyarray`|RTContainedByStrategyNumber 8|Contained| +|`anyarray` % `anyarray`|AnyAarraySimilarityStrategy 16 |Similarity| + + +### Similarity search options + +Set distance type for similarity search. +``` +SET anyarray.similarity_type=cosine; +SET anyarray.similarity_type=jaccard; +SET anyarray.similarity_type=overlap; +``` + +Set threshold for similarity search. +``` +SET anyarray.similarity_threshold = 3; +RESET anyarray.similarity_threshold; +``` + +Examples +------- + +Examples for INTEGER[] . + +### Create a table with sample data. +``` +SELECT t, ARRAY( + SELECT v::int4 + FROM generate_series(max(0, t - 10), t) as v + ) AS v + INTO test_int4 +FROM generate_series(1, 200) as t; +``` + +### Similarity calculation. + +``` +SET anyarray.similarity_type=cosine; +SELECT t, similarity(v, '{10,9,8,7,6,5,4,3,2,1}') AS s FROM test_int4 + WHERE v % '{10,9,8,7,6,5,4,3,2,1}' ORDER BY s DESC, t; +SELECT t, similarity(v, '{50,49,8,7,6,5,4,3,2,1}') AS s FROM test_int4 + WHERE v % '{50,49,8,7,6,5,4,3,2,1}' ORDER BY s DESC, t; + +SET anyarray.similarity_type=jaccard; +SELECT t, similarity(v, '{10,9,8,7,6,5,4,3,2,1}') AS s FROM test_int4 + WHERE v % '{10,9,8,7,6,5,4,3,2,1}' ORDER BY s DESC, t; +SELECT t, similarity(v, '{50,49,8,7,6,5,4,3,2,1}') AS s FROM test_int4 + WHERE v % '{50,49,8,7,6,5,4,3,2,1}' ORDER BY s DESC, t; + +SELECT t, v FROM test_int4 WHERE v && '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v @> '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v <@ '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v = '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=cosine; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=jaccard; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=overlap; +SET anyarray.similarity_threshold = 3; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +RESET anyarray.similarity_threshold; +``` + +### Create GIST index. + +``` +CREATE INDEX idx_test_int4 ON test_int4 USING gist (v _int4_aa_ops); + +SET enable_seqscan=off; + +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v && '{43,50}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v @> '{43,50}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v <@ '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v = '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; + +SELECT t, v FROM test_int4 WHERE v && '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v @> '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v <@ '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v = '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=cosine; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=jaccard; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=overlap; +SET anyarray.similarity_threshold = 3; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +RESET anyarray.similarity_threshold; + +DROP INDEX idx_test_int4; +``` + +### Create GIN index. + +``` +CREATE INDEX idx_test_int4 ON test_int4 USING gin (v _int4_aa_ops); + +SET enable_seqscan=off; + +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v && '{43,50}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v @> '{43,50}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v <@ '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v = '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +EXPLAIN (COSTS OFF) SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; + +SELECT t, v FROM test_int4 WHERE v && '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v @> '{43,50}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v <@ '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SELECT t, v FROM test_int4 WHERE v = '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=cosine; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=jaccard; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +SET anyarray.similarity_type=overlap; +SET anyarray.similarity_threshold = 3; +SELECT t, v FROM test_int4 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; +RESET anyarray.similarity_threshold; +``` + + +Operator class names for all types implemented in anyarray. +----------------------------------------------------------- + +|Type|GIST|GIN| +|----|----|---| +|bit|_bit_aa_ops|_bit_aa_ops| +|bytea|_bytea_aa_ops|_bytea_aa_ops| +|char|_char_aa_ops|_char_aa_ops| +|cidr|_cidr_aa_ops|_cidr_aa_ops| +|date|_date_aa_ops|_date_aa_ops| +|float4|_float4_aa_ops|_float4_aa_ops| +|float8|_float8_aa_ops|_float8_aa_ops| +|inet|_inet_aa_ops|_inet_aa_ops| +|int2|_int2_aa_ops|_int2_aa_ops| +|int4|_int4_aa_ops|_int4_aa_ops| +|int8|_int8_aa_ops|_int8_aa_ops| +|interval|_interval_aa_ops|_interval_aa_ops| +|macaddr|_macaddr_aa_ops|_macaddr_aa_ops| +|money|_money_aa_ops|_money_aa_ops| +|numeric|_numeric_aa_ops|_numeric_aa_ops| +|oid|_oid_aa_ops|_oid_aa_ops| +|text|_text_aa_ops|_text_aa_ops| +|time|_time_aa_ops|_time_aa_ops| +|timestamp|_timestamp_aa_ops|_timestamp_aa_ops| +|timestamptz|_timestamptz_aa_ops|_timestamptz_aa_ops| +|timetz|_timetz_aa_ops|_timetz_aa_ops| +|varbit|_varbit_aa_ops|_varbit_aa_ops| +|varchar|_varchar_aa_ops|_varchar_aa_ops| + +## Upgrading + +Install the latest version and run in every database you want to upgrade: + +``` +ALTER EXTENSION anyarray UPDATE; +``` +You need to close this database server connection to apply changes. + +You can check the version in the current database with psql command: + +``` +\dx +``` + +## Version Notes + +### 1.1 + +Query time of anyarray using GIN indexes decreased. + diff --git a/anyarray--1.0--1.1.sql b/anyarray--1.0--1.1.sql new file mode 100644 index 0000000..ae49880 --- /dev/null +++ b/anyarray--1.0--1.1.sql @@ -0,0 +1,77 @@ +/* + * anyarray version 1.1 + */ + +CREATE OR REPLACE FUNCTION ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE; + +ALTER OPERATOR FAMILY _bit_aa_ops USING gin ADD + FUNCTION 6 (bit[],bit[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _bytea_aa_ops USING gin ADD + FUNCTION 6 (bytea[],bytea[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _char_aa_ops USING gin ADD + FUNCTION 6 (char[],char[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _cidr_aa_ops USING gin ADD + FUNCTION 6 (cidr[],cidr[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _date_aa_ops USING gin ADD + FUNCTION 6 (date[],date[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _float4_aa_ops USING gin ADD + FUNCTION 6 (float4[],float4[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _float8_aa_ops USING gin ADD + FUNCTION 6 (float8[],float8[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _inet_aa_ops USING gin ADD + FUNCTION 6 (inet[],inet[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int2_aa_ops USING gin ADD + FUNCTION 6 (int2[],int2[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int4_aa_ops USING gin ADD + FUNCTION 6 (int4[],int4[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int8_aa_ops USING gin ADD + FUNCTION 6 (int8[],int8[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _interval_aa_ops USING gin ADD + FUNCTION 6 (interval[],interval[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _macaddr_aa_ops USING gin ADD + FUNCTION 6 (macaddr[],macaddr[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _money_aa_ops USING gin ADD + FUNCTION 6 (money[],money[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _numeric_aa_ops USING gin ADD + FUNCTION 6 (numeric[],numeric[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _oid_aa_ops USING gin ADD + FUNCTION 6 (oid[],oid[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _text_aa_ops USING gin ADD + FUNCTION 6 (text[],text[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _time_aa_ops USING gin ADD + FUNCTION 6 (time[],time[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timestamp_aa_ops USING gin ADD + FUNCTION 6 (timestamp[],timestamp[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timestamptz_aa_ops USING gin ADD + FUNCTION 6 (timestamptz[],timestamptz[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timetz_aa_ops USING gin ADD + FUNCTION 6 (timetz[],timetz[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _varbit_aa_ops USING gin ADD + FUNCTION 6 (varbit[],varbit[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _varchar_aa_ops USING gin ADD + FUNCTION 6 (varchar[],varchar[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); diff --git a/anyarray--1.1.sql b/anyarray--1.1.sql new file mode 100644 index 0000000..fcf162a --- /dev/null +++ b/anyarray--1.1.sql @@ -0,0 +1,970 @@ +/* contrib/anyarray/anyarray--1.1.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION anyarray" to load this file. \quit + +-- +-- Create the user-defined type for the 1-D integer arrays (_int4) +-- + +CREATE FUNCTION anyset(anyelement) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_set' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION icount(anyarray) + RETURNS int4 + AS 'MODULE_PATHNAME', 'aa_icount' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR # ( + RIGHTARG = anyarray, + PROCEDURE = icount +); + +CREATE FUNCTION sort(anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_sort' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION sort(anyarray, text) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_sort' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION sort_asc(anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_sort_asc' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION sort_desc(anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_sort_desc' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION uniq(anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_uniq' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION uniq_d(anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_uniqd' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION idx(anyarray, anyelement) + RETURNS int4 + AS 'MODULE_PATHNAME', 'aa_idx' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION subarray(anyarray, int4) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_subarray' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION subarray(anyarray, int4, int4) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_subarray' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR + ( + LEFTARG = anycompatiblearray, + RIGHTARG = anycompatible, + PROCEDURE = array_append +); + +CREATE OPERATOR + ( + LEFTARG = anycompatiblearray, + RIGHTARG = anycompatiblearray, + PROCEDURE = array_cat +); + +CREATE OPERATOR - ( + LEFTARG = anycompatiblearray, + RIGHTARG = anycompatible, + PROCEDURE = array_remove +); + +CREATE FUNCTION subtract_array(anyarray, anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_subtract_array' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR - ( + LEFTARG = anyarray, + RIGHTARG = anyarray, + PROCEDURE = subtract_array +); + +CREATE FUNCTION union_elem(anyarray, anyelement) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_union_elem' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR | ( + LEFTARG = anyarray, + RIGHTARG = anyelement, + PROCEDURE = union_elem +); + +CREATE FUNCTION union_array(anyarray, anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_union_array' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR | ( + LEFTARG = anyarray, + RIGHTARG = anyarray, + PROCEDURE = union_array +); + +CREATE FUNCTION intersect_array(anyarray, anyarray) + RETURNS anyarray + AS 'MODULE_PATHNAME', 'aa_intersect_array' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR & ( + LEFTARG = anyarray, + RIGHTARG = anyarray, + PROCEDURE = intersect_array +); + +CREATE FUNCTION similarity(anyarray, anyarray) + RETURNS float4 + AS 'MODULE_PATHNAME', 'aa_similarity' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION similarity_op(anyarray, anyarray) + RETURNS bool + AS 'MODULE_PATHNAME', 'aa_similarity_op' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR % ( + LEFTARG = anyarray, + RIGHTARG = anyarray, + PROCEDURE = similarity_op, + COMMUTATOR = '%', + RESTRICT = contsel, + JOIN = contjoinsel +); + +CREATE FUNCTION distance(anyarray, anyarray) + RETURNS float4 + AS 'MODULE_PATHNAME', 'aa_distance' + LANGUAGE C STRICT IMMUTABLE; + +CREATE OPERATOR <-> ( + LEFTARG = anyarray, + RIGHTARG = anyarray, + PROCEDURE = distance +); + +--GiST interface + +CREATE FUNCTION ganyarrayin(cstring) + RETURNS ganyarray + AS 'MODULE_PATHNAME' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION ganyarrayout(ganyarray) + RETURNS cstring + AS 'MODULE_PATHNAME' + LANGUAGE C STRICT IMMUTABLE; + +CREATE TYPE ganyarray ( + INTERNALLENGTH = -1, + INPUT = ganyarrayin, + OUTPUT = ganyarrayout +); + +CREATE FUNCTION ganyarray_consistent(internal,internal,int,oid,internal) + RETURNS bool + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_compress(internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_decompress(internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_penalty(internal,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_picksplit(internal, internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_union(bytea, internal) + RETURNS _int4 + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION ganyarray_same(ganyarray, ganyarray, internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + + +--create the operator classes for gist + +CREATE OPERATOR CLASS _int2_aa_ops +FOR TYPE _int2 USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _int4_aa_ops +FOR TYPE _int4 USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _int8_aa_ops +FOR TYPE _int8 USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _float4_aa_ops +FOR TYPE _float4 USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _float8_aa_ops +FOR TYPE _float8 USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _oid_aa_ops +FOR TYPE _oid USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _timestamp_aa_ops +FOR TYPE _timestamp USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _timestamptz_aa_ops +FOR TYPE _timestamptz USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _time_aa_ops +FOR TYPE _time USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _timetz_aa_ops +FOR TYPE _timetz USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _date_aa_ops +FOR TYPE _date USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _interval_aa_ops +FOR TYPE _interval USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _macaddr_aa_ops +FOR TYPE _macaddr USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _inet_aa_ops +FOR TYPE _inet USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _cidr_aa_ops +FOR TYPE _cidr USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _text_aa_ops +FOR TYPE _text USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _varchar_aa_ops +FOR TYPE _varchar USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _char_aa_ops +FOR TYPE _char USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _bytea_aa_ops +FOR TYPE _bytea USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +CREATE OPERATOR CLASS _numeric_aa_ops +FOR TYPE _numeric USING gist +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 ganyarray_consistent(internal,internal,int,oid,internal), + FUNCTION 2 ganyarray_union (bytea, internal), + FUNCTION 3 ganyarray_compress (internal), + FUNCTION 4 ganyarray_decompress (internal), + FUNCTION 5 ganyarray_penalty (internal, internal, internal), + FUNCTION 6 ganyarray_picksplit (internal, internal), + FUNCTION 7 ganyarray_same (ganyarray, ganyarray, internal), +STORAGE ganyarray; + +--gin support functions +CREATE OR REPLACE FUNCTION ginanyarray_extract(anyarray, internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE; + +CREATE OR REPLACE FUNCTION ginanyarray_queryextract(anyarray, internal, internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE; + +CREATE OR REPLACE FUNCTION ginanyarray_consistent(internal, internal, anyarray) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE; + +--gin opclasses + +CREATE OPERATOR CLASS _int2_aa_ops +FOR TYPE _int2 USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btint2cmp(int2,int2), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE int2; +CREATE OPERATOR CLASS _int4_aa_ops +FOR TYPE _int4 USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btint4cmp(int4,int4), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE int4; + +CREATE OPERATOR CLASS _int8_aa_ops +FOR TYPE _int8 USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btint8cmp(int8,int8), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE int8; + +CREATE OPERATOR CLASS _float4_aa_ops +FOR TYPE _float4 USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btfloat4cmp(float4,float4), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE float4; + +CREATE OPERATOR CLASS _float8_aa_ops +FOR TYPE _float8 USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btfloat8cmp(float8,float8), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE float8; + +CREATE OPERATOR CLASS _money_aa_ops +FOR TYPE _money USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 cash_cmp(money,money), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE money; + +CREATE OPERATOR CLASS _oid_aa_ops +FOR TYPE _oid USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btoidcmp(oid,oid), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE oid; + +CREATE OPERATOR CLASS _timestamp_aa_ops +FOR TYPE _timestamp USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 timestamp_cmp(timestamp,timestamp), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE timestamp; + +CREATE OPERATOR CLASS _timestamptz_aa_ops +FOR TYPE _timestamptz USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 timestamptz_cmp(timestamptz,timestamptz), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE timestamptz; + +CREATE OPERATOR CLASS _time_aa_ops +FOR TYPE _time USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 time_cmp(time,time), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE time; + +CREATE OPERATOR CLASS _timetz_aa_ops +FOR TYPE _timetz USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 timetz_cmp(timetz,timetz), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE timetz; + +CREATE OPERATOR CLASS _date_aa_ops +FOR TYPE _date USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 date_cmp(date,date), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE date; + +CREATE OPERATOR CLASS _interval_aa_ops +FOR TYPE _interval USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 interval_cmp(interval,interval), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE interval; + +CREATE OPERATOR CLASS _macaddr_aa_ops +FOR TYPE _macaddr USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 macaddr_cmp(macaddr,macaddr), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE macaddr; + +CREATE OPERATOR CLASS _inet_aa_ops +FOR TYPE _inet USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 network_cmp(inet,inet), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE inet; + +CREATE OPERATOR CLASS _cidr_aa_ops +FOR TYPE _cidr USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 network_cmp(inet,inet), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE cidr; + +CREATE OPERATOR CLASS _text_aa_ops +FOR TYPE _text USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 bttextcmp(text,text), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE text; + +CREATE OPERATOR CLASS _varchar_aa_ops +FOR TYPE _varchar USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 bttextcmp(text,text), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE varchar; + +CREATE OPERATOR CLASS _char_aa_ops +FOR TYPE "_char" USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 btcharcmp("char","char"), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE "char"; + +CREATE OPERATOR CLASS _bytea_aa_ops +FOR TYPE _bytea USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 byteacmp(bytea,bytea), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE bytea; + +CREATE OPERATOR CLASS _bit_aa_ops +FOR TYPE _bit USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 bitcmp(bit,bit), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE bit; + +CREATE OPERATOR CLASS _varbit_aa_ops +FOR TYPE _varbit USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 varbitcmp(varbit,varbit), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE varbit; + +CREATE OPERATOR CLASS _numeric_aa_ops +FOR TYPE _numeric USING gin +AS + OPERATOR 3 && (anyarray, anyarray), + OPERATOR 6 = (anyarray, anyarray), + OPERATOR 7 @> (anyarray, anyarray), + OPERATOR 8 <@ (anyarray, anyarray), + OPERATOR 16 % (anyarray, anyarray), + FUNCTION 1 numeric_cmp(numeric,numeric), + FUNCTION 2 ginanyarray_extract(anyarray, internal), + FUNCTION 3 ginanyarray_queryextract(anyarray, internal, internal), + FUNCTION 4 ginanyarray_consistent(internal, internal, anyarray), + STORAGE numeric; + +CREATE OR REPLACE FUNCTION ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE; + +ALTER OPERATOR FAMILY _bit_aa_ops USING gin ADD + FUNCTION 6 (bit[],bit[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _bytea_aa_ops USING gin ADD + FUNCTION 6 (bytea[],bytea[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _char_aa_ops USING gin ADD + FUNCTION 6 (char[],char[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _cidr_aa_ops USING gin ADD + FUNCTION 6 (cidr[],cidr[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _date_aa_ops USING gin ADD + FUNCTION 6 (date[],date[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _float4_aa_ops USING gin ADD + FUNCTION 6 (float4[],float4[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _float8_aa_ops USING gin ADD + FUNCTION 6 (float8[],float8[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _inet_aa_ops USING gin ADD + FUNCTION 6 (inet[],inet[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int2_aa_ops USING gin ADD + FUNCTION 6 (int2[],int2[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int4_aa_ops USING gin ADD + FUNCTION 6 (int4[],int4[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _int8_aa_ops USING gin ADD + FUNCTION 6 (int8[],int8[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _interval_aa_ops USING gin ADD + FUNCTION 6 (interval[],interval[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _macaddr_aa_ops USING gin ADD + FUNCTION 6 (macaddr[],macaddr[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _money_aa_ops USING gin ADD + FUNCTION 6 (money[],money[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _numeric_aa_ops USING gin ADD + FUNCTION 6 (numeric[],numeric[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _oid_aa_ops USING gin ADD + FUNCTION 6 (oid[],oid[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _text_aa_ops USING gin ADD + FUNCTION 6 (text[],text[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _time_aa_ops USING gin ADD + FUNCTION 6 (time[],time[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timestamp_aa_ops USING gin ADD + FUNCTION 6 (timestamp[],timestamp[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timestamptz_aa_ops USING gin ADD + FUNCTION 6 (timestamptz[],timestamptz[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _timetz_aa_ops USING gin ADD + FUNCTION 6 (timetz[],timetz[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _varbit_aa_ops USING gin ADD + FUNCTION 6 (varbit[],varbit[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + +ALTER OPERATOR FAMILY _varchar_aa_ops USING gin ADD + FUNCTION 6 (varchar[],varchar[]) ginanyarray_triconsistent(internal, internal, anyarray,internal,internal,internal,internal,internal); + diff --git a/anyarray.control b/anyarray.control index 1e7d3dd..bd8f1a6 100644 --- a/anyarray.control +++ b/anyarray.control @@ -1,5 +1,5 @@ # anyarray extension comment = 'functions, operators, and index support for 1-D arrays' -default_version = '1.0' +default_version = '1.1' module_pathname = '$libdir/anyarray' relocatable = true diff --git a/anyarray_gin.c b/anyarray_gin.c index 4946ea9..2d880b9 100644 --- a/anyarray_gin.c +++ b/anyarray_gin.c @@ -194,3 +194,134 @@ ginanyarray_consistent(PG_FUNCTION_ARGS) PG_RETURN_BOOL(res); } + +PG_FUNCTION_INFO_V1(ginanyarray_triconsistent); +Datum +ginanyarray_triconsistent(PG_FUNCTION_ARGS) +{ + GinTernaryValue *check = (GinTernaryValue *)PG_GETARG_POINTER(0); + StrategyNumber strategy = PG_GETARG_UINT16(1); + int32 nkeys = PG_GETARG_INT32(3); + /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ + GinTernaryValue res = GIN_MAYBE; + int32 i; + + switch (strategy) + { + case RTOverlapStrategyNumber: + /* if at least one element in check[] is GIN_TRUE, so result = GIN_TRUE + * otherwise if at least one element in check[] is GIN_MAYBE, so result = GIN_MAYBE + * otherwise result = GIN_FALSE + */ + res = GIN_FALSE; + for (i = 0; i < nkeys; i++) + { + if (check[i] == GIN_TRUE) + { + res = GIN_TRUE; + break; + } else if (check[i] == GIN_MAYBE) + { + res = GIN_MAYBE; + } + } + break; + case RTContainedByStrategyNumber: + /* at least one element in check[] is GIN_TRUE or GIN_MAYBE, so result = GIN_MAYBE (we will need recheck in any case) */ + res = GIN_MAYBE; + break; + case RTSameStrategyNumber: + /* if at least one element in check[] is GIN_FALSE, so result = GIN_FALSE + * otherwise result = GIN_MAYBE + */ + res = GIN_MAYBE; + for (i = 0; i < nkeys; i++) + { + if (check[i] == GIN_FALSE) + { + res = GIN_FALSE; + break; + } + } + break; + case RTContainsStrategyNumber: + /* if at least one element in check[] is GIN_FALSE, so result = GIN_FALSE + * otherwise if at least one element in check[] is GIN_MAYBE, so result = GIN_MAYBE + * otherwise result = GIN_TRUE + */ + res = GIN_TRUE; + for (i = 0; i < nkeys; i++) + { + if (check[i] == GIN_FALSE) + { + res = GIN_FALSE; + break; + } else if (check[i] == GIN_MAYBE) + { + res = GIN_MAYBE; + } + } + break; + case AnyAarraySimilarityStrategy: + { + int32 nIntersectionMin = 0; + int32 nIntersectionMax = 0; + + res = GIN_FALSE; + for (i = 0; i < nkeys; i++) + { + if (check[i] == GIN_TRUE) + { + nIntersectionMin++; + nIntersectionMax++; + } else if (check[i] == GIN_MAYBE) + { + nIntersectionMax++; + res = GIN_MAYBE; + } + } + + switch(SmlType) + { + case AA_Cosine: + /* nIntersection / sqrt(nkeys * nIntersection) */ + if(sqrt(((double)nIntersectionMax) / (double)nkeys) < SmlLimit){ + res = GIN_FALSE; + } else { + res = GIN_MAYBE; + } + break; + case AA_Jaccard: + if((((double)nIntersectionMax) / (double)nkeys) < SmlLimit){ + res = GIN_FALSE; + } else { + res = GIN_MAYBE; + } + break; + case AA_Overlap: + /* nIntersectionMin - quantity of GIN_TRUE in check array + * nIntersectionMax - quantity of GIN_TRUE and GIN_MAYBE in check array + * if nIntersectionMin >= SmlLimit, so result = GIN_TRUE + * if nIntersectionMax < SmlLimit, so result = GIN_FALSE + * otherwise if at least one element in check[] is GIN_MAYBE, so result = GIN_MAYBE + * otherwise result = GIN_FALSE + */ + if(((double)nIntersectionMin) >= SmlLimit) + { + res = GIN_TRUE; + } else if(((double)nIntersectionMax) < SmlLimit) + { + res = GIN_FALSE; + } + break; + default: + elog(ERROR, "unknown similarity type"); + } + } + break; + default: + elog(ERROR, "ginanyarray_triconsistent: unknown strategy number: %d", + strategy); + } + PG_RETURN_GIN_TERNARY_VALUE(res); +} diff --git a/sql/int8.sql b/sql/int8.sql index f1cd348..5e7a056 100644 --- a/sql/int8.sql +++ b/sql/int8.sql @@ -79,7 +79,7 @@ SELECT t, v FROM test_int8 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; SET anyarray.similarity_type=jaccard; SELECT t, v FROM test_int8 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; SET anyarray.similarity_type=overlap; -SET anyarray.similarity_threshold = 3; + SET anyarray.similarity_threshold = 3; SELECT t, v FROM test_int8 WHERE v % '{0,1,2,3,4,5,6,7,8,9,10}' ORDER BY t; RESET anyarray.similarity_threshold;