From 53cc7c9813ac43aeb1e3f19a2b30da41f2704114 Mon Sep 17 00:00:00 2001 From: Varik Matevosyan Date: Tue, 5 Nov 2024 12:17:31 +0400 Subject: [PATCH] add update path to 0.8.0-lanterncloud version, fixes for pg17 --- ...0.7.4-lanterncloud--0.8.0-lanterncloud.sql | 35 + sql/vector--0.8.0-lanterncloud.sql | 918 ++++++++++++++++++ sql/vector.sql | 12 + src/hnsw.c | 2 +- src/hnswbuild.c | 3 + src/hnswexternal.c | 51 +- 6 files changed, 1012 insertions(+), 9 deletions(-) create mode 100644 sql/vector--0.7.4-lanterncloud--0.8.0-lanterncloud.sql create mode 100644 sql/vector--0.8.0-lanterncloud.sql diff --git a/sql/vector--0.7.4-lanterncloud--0.8.0-lanterncloud.sql b/sql/vector--0.7.4-lanterncloud--0.8.0-lanterncloud.sql new file mode 100644 index 00000000..32efe487 --- /dev/null +++ b/sql/vector--0.7.4-lanterncloud--0.8.0-lanterncloud.sql @@ -0,0 +1,35 @@ +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION vector UPDATE TO '0.8.0-lanterncloud'" to load this file. \quit + +DROP CAST IF EXISTS (integer[] AS sparsevec); +DROP CAST IF EXISTS (real[] AS sparsevec); +DROP CAST IF EXISTS (double precision[] AS sparsevec); +DROP CAST IF EXISTS (numeric[] AS sparsevec); +DROP FUNCTION IF EXISTS array_to_sparsevec(integer[], integer, boolean); +DROP FUNCTION IF EXISTS array_to_sparsevec(real[], integer, boolean); +DROP FUNCTION IF EXISTS array_to_sparsevec(double precision[], integer, boolean); +DROP FUNCTION IF EXISTS array_to_sparsevec(numeric[], integer, boolean); + +CREATE FUNCTION array_to_sparsevec(integer[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(real[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(double precision[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(numeric[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE CAST (integer[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(integer[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (real[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(real[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (double precision[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(double precision[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (numeric[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(numeric[], integer, boolean) AS ASSIGNMENT; diff --git a/sql/vector--0.8.0-lanterncloud.sql b/sql/vector--0.8.0-lanterncloud.sql new file mode 100644 index 00000000..7fc36712 --- /dev/null +++ b/sql/vector--0.8.0-lanterncloud.sql @@ -0,0 +1,918 @@ +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION vector" to load this file. \quit + +-- vector type + +CREATE TYPE vector; + +CREATE FUNCTION vector_in(cstring, oid, integer) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_out(vector) RETURNS cstring + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_typmod_in(cstring[]) RETURNS integer + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_recv(internal, oid, integer) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_send(vector) RETURNS bytea + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE TYPE vector ( + INPUT = vector_in, + OUTPUT = vector_out, + TYPMOD_IN = vector_typmod_in, + RECEIVE = vector_recv, + SEND = vector_send, + STORAGE = external +); + +-- vector functions + +CREATE FUNCTION l2_distance(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION inner_product(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION cosine_distance(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l1_distance(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_dims(vector) RETURNS integer + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_norm(vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l2_normalize(vector) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION binary_quantize(vector) RETURNS bit + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION subvector(vector, int, int) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- vector private functions + +CREATE FUNCTION vector_add(vector, vector) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_sub(vector, vector) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_mul(vector, vector) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_concat(vector, vector) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_lt(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_le(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_eq(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_ne(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_ge(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_gt(vector, vector) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_cmp(vector, vector) RETURNS int4 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_l2_squared_distance(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_negative_inner_product(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_spherical_distance(vector, vector) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_accum(double precision[], vector) RETURNS double precision[] + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_avg(double precision[]) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_combine(double precision[], double precision[]) RETURNS double precision[] + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- vector aggregates + +CREATE AGGREGATE avg(vector) ( + SFUNC = vector_accum, + STYPE = double precision[], + FINALFUNC = vector_avg, + COMBINEFUNC = vector_combine, + INITCOND = '{0}', + PARALLEL = SAFE +); + +CREATE AGGREGATE sum(vector) ( + SFUNC = vector_add, + STYPE = vector, + COMBINEFUNC = vector_add, + PARALLEL = SAFE +); + +-- vector cast functions + +CREATE FUNCTION vector(vector, integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_vector(integer[], integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_vector(real[], integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_vector(double precision[], integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_vector(numeric[], integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_to_float4(vector, integer, boolean) RETURNS real[] + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- vector casts + +CREATE CAST (vector AS vector) + WITH FUNCTION vector(vector, integer, boolean) AS IMPLICIT; + +CREATE CAST (vector AS real[]) + WITH FUNCTION vector_to_float4(vector, integer, boolean) AS IMPLICIT; + +CREATE CAST (integer[] AS vector) + WITH FUNCTION array_to_vector(integer[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (real[] AS vector) + WITH FUNCTION array_to_vector(real[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (double precision[] AS vector) + WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (numeric[] AS vector) + WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS ASSIGNMENT; + +-- vector operators + +CREATE OPERATOR <-> ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = l2_distance, + COMMUTATOR = '<->' +); + +CREATE OPERATOR <#> ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_negative_inner_product, + COMMUTATOR = '<#>' +); + +CREATE OPERATOR <=> ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = cosine_distance, + COMMUTATOR = '<=>' +); + +CREATE OPERATOR <+> ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = l1_distance, + COMMUTATOR = '<+>' +); + +CREATE OPERATOR + ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_add, + COMMUTATOR = + +); + +CREATE OPERATOR - ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub +); + +CREATE OPERATOR * ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_mul, + COMMUTATOR = * +); + +CREATE OPERATOR || ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_concat +); + +CREATE OPERATOR < ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_lt, + COMMUTATOR = > , NEGATOR = >= , + RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_le, + COMMUTATOR = >= , NEGATOR = > , + RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR = ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_eq, + COMMUTATOR = = , NEGATOR = <> , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ne, + COMMUTATOR = <> , NEGATOR = = , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR >= ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ge, + COMMUTATOR = <= , NEGATOR = < , + RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR > ( + LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_gt, + COMMUTATOR = < , NEGATOR = <= , + RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +-- access methods + +CREATE FUNCTION ivfflathandler(internal) RETURNS index_am_handler + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE ACCESS METHOD ivfflat TYPE INDEX HANDLER ivfflathandler; + +COMMENT ON ACCESS METHOD ivfflat IS 'ivfflat index access method'; + +CREATE FUNCTION hnswhandler(internal) RETURNS index_am_handler + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE ACCESS METHOD hnsw TYPE INDEX HANDLER hnswhandler; + +COMMENT ON ACCESS METHOD hnsw IS 'hnsw index access method'; + +-- access method private functions + +CREATE FUNCTION ivfflat_halfvec_support(internal) RETURNS internal + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION ivfflat_bit_support(internal) RETURNS internal + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION hnsw_halfvec_support(internal) RETURNS internal + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION hnsw_bit_support(internal) RETURNS internal + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION hnsw_sparsevec_support(internal) RETURNS internal + AS 'MODULE_PATHNAME' LANGUAGE C; + +-- vector opclasses + +CREATE OPERATOR CLASS vector_ops + DEFAULT FOR TYPE vector USING btree AS + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 vector_cmp(vector, vector); + +CREATE OPERATOR CLASS vector_l2_ops + DEFAULT FOR TYPE vector USING ivfflat AS + OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_l2_squared_distance(vector, vector), + FUNCTION 3 l2_distance(vector, vector); + +CREATE OPERATOR CLASS vector_ip_ops + FOR TYPE vector USING ivfflat AS + OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_negative_inner_product(vector, vector), + FUNCTION 3 vector_spherical_distance(vector, vector), + FUNCTION 4 vector_norm(vector); + +CREATE OPERATOR CLASS vector_cosine_ops + FOR TYPE vector USING ivfflat AS + OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_negative_inner_product(vector, vector), + FUNCTION 2 vector_norm(vector), + FUNCTION 3 vector_spherical_distance(vector, vector), + FUNCTION 4 vector_norm(vector); + +CREATE OPERATOR CLASS vector_l2_ops + FOR TYPE vector USING hnsw AS + OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_l2_squared_distance(vector, vector); + +CREATE OPERATOR CLASS vector_ip_ops + FOR TYPE vector USING hnsw AS + OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_negative_inner_product(vector, vector); + +CREATE OPERATOR CLASS vector_cosine_ops + FOR TYPE vector USING hnsw AS + OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 vector_negative_inner_product(vector, vector), + FUNCTION 2 vector_norm(vector); + +CREATE OPERATOR CLASS vector_l1_ops + FOR TYPE vector USING hnsw AS + OPERATOR 1 <+> (vector, vector) FOR ORDER BY float_ops, + FUNCTION 1 l1_distance(vector, vector); + +-- halfvec type + +CREATE TYPE halfvec; + +CREATE FUNCTION halfvec_in(cstring, oid, integer) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_out(halfvec) RETURNS cstring + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_typmod_in(cstring[]) RETURNS integer + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_recv(internal, oid, integer) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_send(halfvec) RETURNS bytea + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE TYPE halfvec ( + INPUT = halfvec_in, + OUTPUT = halfvec_out, + TYPMOD_IN = halfvec_typmod_in, + RECEIVE = halfvec_recv, + SEND = halfvec_send, + STORAGE = external +); + +-- halfvec functions + +CREATE FUNCTION l2_distance(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME', 'halfvec_l2_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION inner_product(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME', 'halfvec_inner_product' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION cosine_distance(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME', 'halfvec_cosine_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_dims(halfvec) RETURNS integer + AS 'MODULE_PATHNAME', 'halfvec_vector_dims' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l2_norm(halfvec) RETURNS float8 + AS 'MODULE_PATHNAME', 'halfvec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l2_normalize(halfvec) RETURNS halfvec + AS 'MODULE_PATHNAME', 'halfvec_l2_normalize' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION binary_quantize(halfvec) RETURNS bit + AS 'MODULE_PATHNAME', 'halfvec_binary_quantize' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION subvector(halfvec, int, int) RETURNS halfvec + AS 'MODULE_PATHNAME', 'halfvec_subvector' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- halfvec private functions + +CREATE FUNCTION halfvec_add(halfvec, halfvec) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_sub(halfvec, halfvec) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_mul(halfvec, halfvec) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_concat(halfvec, halfvec) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_lt(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_le(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_eq(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_ne(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_ge(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_gt(halfvec, halfvec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_cmp(halfvec, halfvec) RETURNS int4 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_negative_inner_product(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_spherical_distance(halfvec, halfvec) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_accum(double precision[], halfvec) RETURNS double precision[] + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_avg(double precision[]) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_combine(double precision[], double precision[]) RETURNS double precision[] + AS 'MODULE_PATHNAME', 'vector_combine' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- halfvec aggregates + +CREATE AGGREGATE avg(halfvec) ( + SFUNC = halfvec_accum, + STYPE = double precision[], + FINALFUNC = halfvec_avg, + COMBINEFUNC = halfvec_combine, + INITCOND = '{0}', + PARALLEL = SAFE +); + +CREATE AGGREGATE sum(halfvec) ( + SFUNC = halfvec_add, + STYPE = halfvec, + COMBINEFUNC = halfvec_add, + PARALLEL = SAFE +); + +-- halfvec cast functions + +CREATE FUNCTION halfvec(halfvec, integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_to_vector(halfvec, integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_to_halfvec(vector, integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_halfvec(integer[], integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_halfvec(real[], integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_halfvec(double precision[], integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_halfvec(numeric[], integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_to_float4(halfvec, integer, boolean) RETURNS real[] + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- halfvec casts + +CREATE CAST (halfvec AS halfvec) + WITH FUNCTION halfvec(halfvec, integer, boolean) AS IMPLICIT; + +CREATE CAST (halfvec AS vector) + WITH FUNCTION halfvec_to_vector(halfvec, integer, boolean) AS ASSIGNMENT; + +CREATE CAST (vector AS halfvec) + WITH FUNCTION vector_to_halfvec(vector, integer, boolean) AS IMPLICIT; + +CREATE CAST (halfvec AS real[]) + WITH FUNCTION halfvec_to_float4(halfvec, integer, boolean) AS ASSIGNMENT; + +CREATE CAST (integer[] AS halfvec) + WITH FUNCTION array_to_halfvec(integer[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (real[] AS halfvec) + WITH FUNCTION array_to_halfvec(real[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (double precision[] AS halfvec) + WITH FUNCTION array_to_halfvec(double precision[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (numeric[] AS halfvec) + WITH FUNCTION array_to_halfvec(numeric[], integer, boolean) AS ASSIGNMENT; + +-- halfvec operators + +CREATE OPERATOR <-> ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = l2_distance, + COMMUTATOR = '<->' +); + +CREATE OPERATOR <#> ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_negative_inner_product, + COMMUTATOR = '<#>' +); + +CREATE OPERATOR <=> ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = cosine_distance, + COMMUTATOR = '<=>' +); + +CREATE OPERATOR <+> ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = l1_distance, + COMMUTATOR = '<+>' +); + +CREATE OPERATOR + ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_add, + COMMUTATOR = + +); + +CREATE OPERATOR - ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_sub +); + +CREATE OPERATOR * ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_mul, + COMMUTATOR = * +); + +CREATE OPERATOR || ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_concat +); + +CREATE OPERATOR < ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_lt, + COMMUTATOR = > , NEGATOR = >= , + RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_le, + COMMUTATOR = >= , NEGATOR = > , + RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR = ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_eq, + COMMUTATOR = = , NEGATOR = <> , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ne, + COMMUTATOR = <> , NEGATOR = = , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR >= ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ge, + COMMUTATOR = <= , NEGATOR = < , + RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR > ( + LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_gt, + COMMUTATOR = < , NEGATOR = <= , + RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +-- halfvec opclasses + +CREATE OPERATOR CLASS halfvec_ops + DEFAULT FOR TYPE halfvec USING btree AS + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 halfvec_cmp(halfvec, halfvec); + +CREATE OPERATOR CLASS halfvec_l2_ops + FOR TYPE halfvec USING ivfflat AS + OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_l2_squared_distance(halfvec, halfvec), + FUNCTION 3 l2_distance(halfvec, halfvec), + FUNCTION 5 ivfflat_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_ip_ops + FOR TYPE halfvec USING ivfflat AS + OPERATOR 1 <#> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec), + FUNCTION 3 halfvec_spherical_distance(halfvec, halfvec), + FUNCTION 4 l2_norm(halfvec), + FUNCTION 5 ivfflat_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_cosine_ops + FOR TYPE halfvec USING ivfflat AS + OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec), + FUNCTION 2 l2_norm(halfvec), + FUNCTION 3 halfvec_spherical_distance(halfvec, halfvec), + FUNCTION 4 l2_norm(halfvec), + FUNCTION 5 ivfflat_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_l2_ops + FOR TYPE halfvec USING hnsw AS + OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_l2_squared_distance(halfvec, halfvec), + FUNCTION 3 hnsw_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_ip_ops + FOR TYPE halfvec USING hnsw AS + OPERATOR 1 <#> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec), + FUNCTION 3 hnsw_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_cosine_ops + FOR TYPE halfvec USING hnsw AS + OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec), + FUNCTION 2 l2_norm(halfvec), + FUNCTION 3 hnsw_halfvec_support(internal); + +CREATE OPERATOR CLASS halfvec_l1_ops + FOR TYPE halfvec USING hnsw AS + OPERATOR 1 <+> (halfvec, halfvec) FOR ORDER BY float_ops, + FUNCTION 1 l1_distance(halfvec, halfvec), + FUNCTION 3 hnsw_halfvec_support(internal); + +-- bit functions + +CREATE FUNCTION hamming_distance(bit, bit) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION jaccard_distance(bit, bit) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- bit operators + +CREATE OPERATOR <~> ( + LEFTARG = bit, RIGHTARG = bit, PROCEDURE = hamming_distance, + COMMUTATOR = '<~>' +); + +CREATE OPERATOR <%> ( + LEFTARG = bit, RIGHTARG = bit, PROCEDURE = jaccard_distance, + COMMUTATOR = '<%>' +); + +-- bit opclasses + +CREATE OPERATOR CLASS bit_hamming_ops + FOR TYPE bit USING ivfflat AS + OPERATOR 1 <~> (bit, bit) FOR ORDER BY float_ops, + FUNCTION 1 hamming_distance(bit, bit), + FUNCTION 3 hamming_distance(bit, bit), + FUNCTION 5 ivfflat_bit_support(internal); + +CREATE OPERATOR CLASS bit_hamming_ops + FOR TYPE bit USING hnsw AS + OPERATOR 1 <~> (bit, bit) FOR ORDER BY float_ops, + FUNCTION 1 hamming_distance(bit, bit), + FUNCTION 3 hnsw_bit_support(internal); + +CREATE OPERATOR CLASS bit_jaccard_ops + FOR TYPE bit USING hnsw AS + OPERATOR 1 <%> (bit, bit) FOR ORDER BY float_ops, + FUNCTION 1 jaccard_distance(bit, bit), + FUNCTION 3 hnsw_bit_support(internal); + +--- sparsevec type + +CREATE TYPE sparsevec; + +CREATE FUNCTION sparsevec_in(cstring, oid, integer) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_out(sparsevec) RETURNS cstring + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_typmod_in(cstring[]) RETURNS integer + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_recv(internal, oid, integer) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_send(sparsevec) RETURNS bytea + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE TYPE sparsevec ( + INPUT = sparsevec_in, + OUTPUT = sparsevec_out, + TYPMOD_IN = sparsevec_typmod_in, + RECEIVE = sparsevec_recv, + SEND = sparsevec_send, + STORAGE = external +); + +-- sparsevec functions + +CREATE FUNCTION l2_distance(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME', 'sparsevec_l2_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION inner_product(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME', 'sparsevec_inner_product' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION cosine_distance(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME', 'sparsevec_cosine_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l1_distance(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME', 'sparsevec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l2_norm(sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME', 'sparsevec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION l2_normalize(sparsevec) RETURNS sparsevec + AS 'MODULE_PATHNAME', 'sparsevec_l2_normalize' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- sparsevec private functions + +CREATE FUNCTION sparsevec_lt(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_le(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_eq(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_ne(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_ge(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_gt(sparsevec, sparsevec) RETURNS bool + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_cmp(sparsevec, sparsevec) RETURNS int4 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_l2_squared_distance(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_negative_inner_product(sparsevec, sparsevec) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- sparsevec cast functions + +CREATE FUNCTION sparsevec(sparsevec, integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION vector_to_sparsevec(vector, integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_to_vector(sparsevec, integer, boolean) RETURNS vector + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION halfvec_to_sparsevec(halfvec, integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION sparsevec_to_halfvec(sparsevec, integer, boolean) RETURNS halfvec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(integer[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(real[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(double precision[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION array_to_sparsevec(numeric[], integer, boolean) RETURNS sparsevec + AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +-- sparsevec casts + +CREATE CAST (sparsevec AS sparsevec) + WITH FUNCTION sparsevec(sparsevec, integer, boolean) AS IMPLICIT; + +CREATE CAST (sparsevec AS vector) + WITH FUNCTION sparsevec_to_vector(sparsevec, integer, boolean) AS ASSIGNMENT; + +CREATE CAST (vector AS sparsevec) + WITH FUNCTION vector_to_sparsevec(vector, integer, boolean) AS IMPLICIT; + +CREATE CAST (sparsevec AS halfvec) + WITH FUNCTION sparsevec_to_halfvec(sparsevec, integer, boolean) AS ASSIGNMENT; + +CREATE CAST (halfvec AS sparsevec) + WITH FUNCTION halfvec_to_sparsevec(halfvec, integer, boolean) AS IMPLICIT; + +CREATE CAST (integer[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(integer[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (real[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(real[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (double precision[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(double precision[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (numeric[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(numeric[], integer, boolean) AS ASSIGNMENT; + +-- sparsevec operators + +CREATE OPERATOR <-> ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = l2_distance, + COMMUTATOR = '<->' +); + +CREATE OPERATOR <#> ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_negative_inner_product, + COMMUTATOR = '<#>' +); + +CREATE OPERATOR <=> ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = cosine_distance, + COMMUTATOR = '<=>' +); + +CREATE OPERATOR <+> ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = l1_distance, + COMMUTATOR = '<+>' +); + +CREATE OPERATOR < ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_lt, + COMMUTATOR = > , NEGATOR = >= , + RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_le, + COMMUTATOR = >= , NEGATOR = > , + RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR = ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_eq, + COMMUTATOR = = , NEGATOR = <> , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_ne, + COMMUTATOR = <> , NEGATOR = = , + RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR >= ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_ge, + COMMUTATOR = <= , NEGATOR = < , + RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR > ( + LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_gt, + COMMUTATOR = < , NEGATOR = <= , + RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +-- sparsevec opclasses + +CREATE OPERATOR CLASS sparsevec_ops + DEFAULT FOR TYPE sparsevec USING btree AS + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 sparsevec_cmp(sparsevec, sparsevec); + +CREATE OPERATOR CLASS sparsevec_l2_ops + FOR TYPE sparsevec USING hnsw AS + OPERATOR 1 <-> (sparsevec, sparsevec) FOR ORDER BY float_ops, + FUNCTION 1 sparsevec_l2_squared_distance(sparsevec, sparsevec), + FUNCTION 3 hnsw_sparsevec_support(internal); + +CREATE OPERATOR CLASS sparsevec_ip_ops + FOR TYPE sparsevec USING hnsw AS + OPERATOR 1 <#> (sparsevec, sparsevec) FOR ORDER BY float_ops, + FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec), + FUNCTION 3 hnsw_sparsevec_support(internal); + +CREATE OPERATOR CLASS sparsevec_cosine_ops + FOR TYPE sparsevec USING hnsw AS + OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops, + FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec), + FUNCTION 2 l2_norm(sparsevec), + FUNCTION 3 hnsw_sparsevec_support(internal); + +CREATE OPERATOR CLASS sparsevec_l1_ops + FOR TYPE sparsevec USING hnsw AS + OPERATOR 1 <+> (sparsevec, sparsevec) FOR ORDER BY float_ops, + FUNCTION 1 l1_distance(sparsevec, sparsevec), + FUNCTION 3 hnsw_sparsevec_support(internal); diff --git a/sql/vector.sql b/sql/vector.sql index 89f76da1..7fc36712 100644 --- a/sql/vector.sql +++ b/sql/vector.sql @@ -811,6 +811,18 @@ CREATE CAST (sparsevec AS halfvec) CREATE CAST (halfvec AS sparsevec) WITH FUNCTION halfvec_to_sparsevec(halfvec, integer, boolean) AS IMPLICIT; +CREATE CAST (integer[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(integer[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (real[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(real[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (double precision[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(double precision[], integer, boolean) AS ASSIGNMENT; + +CREATE CAST (numeric[] AS sparsevec) + WITH FUNCTION array_to_sparsevec(numeric[], integer, boolean) AS ASSIGNMENT; + -- sparsevec operators CREATE OPERATOR <-> ( diff --git a/src/hnsw.c b/src/hnsw.c index 84fe5c37..c7773681 100644 --- a/src/hnsw.c +++ b/src/hnsw.c @@ -121,7 +121,7 @@ HnswInit(void) "Use SSL connection when connecting to external index socket", "Set this to 0 to disable secure connection", &hnsw_external_index_secure, - true, + false, PGC_USERSET, 0, NULL, diff --git a/src/hnswbuild.c b/src/hnswbuild.c index 47c15bf2..6dafc3fa 100644 --- a/src/hnswbuild.c +++ b/src/hnswbuild.c @@ -714,6 +714,9 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index buildstate->hnswleader = NULL; buildstate->hnswshared = NULL; buildstate->hnswarea = NULL; + + buildstate->usearch_index = NULL; + buildstate->external_socket = NULL; } /* diff --git a/src/hnswexternal.c b/src/hnswexternal.c index c05ffba0..d271f406 100644 --- a/src/hnswexternal.c +++ b/src/hnswexternal.c @@ -14,6 +14,7 @@ #include "access/xloginsert.h" #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/pg_proc.h" #include "catalog/pg_type_d.h" #include "commands/progress.h" #include "miscadmin.h" @@ -22,6 +23,7 @@ #include "tcop/tcopprot.h" #include "utils/datum.h" #include "utils/memutils.h" +#include "executor/spi.h" #include "external_index_socket.h" #include "halfvec.h" @@ -44,6 +46,36 @@ #define CALLBACK_ITEM_POINTER HeapTuple hup #endif +static Oid TypenameGetVectorTypid(char *typename) { + int ret; + Oid result_oid = 0; + char query[256]; + + snprintf(query, sizeof(query), + "SELECT pg_type.oid FROM pg_type " + "JOIN pg_depend ON pg_type.oid = pg_depend.objid " + "JOIN pg_extension ON pg_depend.refobjid = pg_extension.oid " + "WHERE typname='%s' AND extname='vector'" +, typename); + + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); + + ret = SPI_exec(query, 1); + + if (ret == SPI_OK_SELECT && SPI_processed > 0) + { + bool isnull; + Datum result_datum = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); + + if (!isnull) + result_oid = DatumGetObjectId(result_datum); + } + + SPI_finish(); + return result_oid; +} + static usearch_label_t ItemPointer2Label(ItemPointer itemPtr) { usearch_label_t label = 0; memcpy(&label, itemPtr, sizeof(*itemPtr)); @@ -170,8 +202,8 @@ static void ImportExternalIndexInternal(Relation heap, Relation index, tupleDesc = RelationGetDescr(heap); attr = &tupleDesc->attrs[index->rd_index->indkey.values[0] - 1]; columnType = attr->atttypid; - Vector_Oid = TypenameGetTypid("vector"); - HalfVector_Oid = TypenameGetTypid("halfvec"); + Vector_Oid = TypenameGetVectorTypid("vector"); + HalfVector_Oid = TypenameGetVectorTypid("halfvec"); opts.dimensions = buildstate->dimensions; opts.connectivity = buildstate->m; @@ -189,11 +221,13 @@ static void ImportExternalIndexInternal(Relation heap, Relation index, elog(ERROR, "unsupported element type for external indexing"); } - if (buildstate->procinfo->fn_addr == vector_negative_inner_product || - buildstate->procinfo->fn_addr == halfvec_negative_inner_product) { + if (buildstate->support.procinfo->fn_addr == vector_negative_inner_product || + buildstate->support.procinfo->fn_addr == halfvec_negative_inner_product) { opts.metric_kind = usearch_metric_cos_k; - } else if (buildstate->procinfo->fn_addr == vector_l2_squared_distance || - buildstate->procinfo->fn_addr == halfvec_l2_squared_distance) { + } else if (buildstate->support.procinfo->fn_addr == + vector_l2_squared_distance || + buildstate->support.procinfo->fn_addr == + halfvec_l2_squared_distance) { opts.metric_kind = usearch_metric_l2sq_k; } else { elog(ERROR, "unsupported distance metric for external indexing"); @@ -316,7 +350,6 @@ static void ImportExternalIndexInternal(Relation heap, Relation index, /* Create Neighbor Tuple */ ntup->type = HNSW_NEIGHBOR_TUPLE_TYPE; ntup->count = (node_level + 2) * metadata.connectivity; - ntup->unused = 0; neighbor_len = 0; @@ -453,7 +486,9 @@ void ImportExternalIndex(Relation heap, Relation index, IndexInfo *indexInfo, HnswBuildState *buildstate, ForkNumber forkNum) { usearch_error_t error = NULL; PG_TRY(); - { ImportExternalIndexInternal(heap, index, indexInfo, buildstate, forkNum); } + { + ImportExternalIndexInternal(heap, index, indexInfo, buildstate, forkNum); + } PG_CATCH(); { if (buildstate->usearch_index) {