/* <begin connected objects> */
/*
This file is auto generated by pgrx.

The ordering of items is not stable, it is driven by a dependency graph.
*/
/* </end connected objects> */

/* <begin connected objects> */
-- src/lib.rs:46
-- bootstrap
-- List of shell types

CREATE TYPE scalar8;
CREATE TYPE sphere_vector;
CREATE TYPE sphere_halfvec;
CREATE TYPE sphere_scalar8;
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_halfvec.rs:93
-- vchord::datatype::operators_halfvec::_vchord_halfvec_operator_maxsim
CREATE  FUNCTION "_vchord_halfvec_operator_maxsim"(
    "lhs" halfvec[], /* pgrx::datum::array::Array<vchord::datatype::memory_halfvec::HalfvecInput> */
    "rhs" halfvec[] /* pgrx::datum::array::Array<vchord::datatype::memory_halfvec::HalfvecInput> */
) RETURNS real /* f32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_halfvec_operator_maxsim_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/functions_scalar8.rs:31
-- vchord::datatype::functions_scalar8::_vchord_halfvec_quantize_to_scalar8
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_halfvec.rs:69
-- vchord::datatype::operators_halfvec::_vchord_halfvec_sphere_cosine_in
CREATE  FUNCTION "_vchord_halfvec_sphere_cosine_in"(
    "lhs" halfvec, /* vchord::datatype::memory_halfvec::HalfvecInput */
    "rhs" sphere_halfvec /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_halfvec_sphere_cosine_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_halfvec.rs:45
-- vchord::datatype::operators_halfvec::_vchord_halfvec_sphere_ip_in
CREATE  FUNCTION "_vchord_halfvec_sphere_ip_in"(
    "lhs" halfvec, /* vchord::datatype::memory_halfvec::HalfvecInput */
    "rhs" sphere_halfvec /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_halfvec_sphere_ip_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_halfvec.rs:21
-- vchord::datatype::operators_halfvec::_vchord_halfvec_sphere_l2_in
CREATE  FUNCTION "_vchord_halfvec_sphere_l2_in"(
    "lhs" halfvec, /* vchord::datatype::memory_halfvec::HalfvecInput */
    "rhs" sphere_halfvec /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_halfvec_sphere_l2_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/text_scalar8.rs:20
-- vchord::datatype::text_scalar8::_vchord_scalar8_in
CREATE  FUNCTION "_vchord_scalar8_in"(
    "input" cstring, /* &core::ffi::c_str::CStr */
    "oid" oid, /* pgrx_pg_sys::submodules::oids::Oid */
    "typmod" INT /* i32 */
) RETURNS scalar8 /* vchord::datatype::memory_scalar8::Scalar8Output */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:40
-- vchord::datatype::operators_scalar8::_vchord_scalar8_operator_cosine
CREATE  FUNCTION "_vchord_scalar8_operator_cosine"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" scalar8 /* vchord::datatype::memory_scalar8::Scalar8Input */
) RETURNS real /* f32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_operator_cosine_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:20
-- vchord::datatype::operators_scalar8::_vchord_scalar8_operator_ip
CREATE  FUNCTION "_vchord_scalar8_operator_ip"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" scalar8 /* vchord::datatype::memory_scalar8::Scalar8Input */
) RETURNS real /* f32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_operator_ip_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:30
-- vchord::datatype::operators_scalar8::_vchord_scalar8_operator_l2
CREATE  FUNCTION "_vchord_scalar8_operator_l2"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" scalar8 /* vchord::datatype::memory_scalar8::Scalar8Input */
) RETURNS real /* f32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_operator_l2_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/text_scalar8.rs:132
-- vchord::datatype::text_scalar8::_vchord_scalar8_out
CREATE  FUNCTION "_vchord_scalar8_out"(
    "vector" scalar8 /* vchord::datatype::memory_scalar8::Scalar8Input */
) RETURNS cstring /* alloc::ffi::c_str::CString */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_out_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/binary_scalar8.rs:36
-- vchord::datatype::binary_scalar8::_vchord_scalar8_recv
CREATE  FUNCTION "_vchord_scalar8_recv"(
    "internal" internal, /* pgrx::datum::internal::Internal */
    "oid" oid, /* pgrx_pg_sys::submodules::oids::Oid */
    "typmod" INT /* i32 */
) RETURNS scalar8 /* vchord::datatype::memory_scalar8::Scalar8Output */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_recv_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/binary_scalar8.rs:21
-- vchord::datatype::binary_scalar8::_vchord_scalar8_send
CREATE  FUNCTION "_vchord_scalar8_send"(
    "vector" scalar8 /* vchord::datatype::memory_scalar8::Scalar8Input */
) RETURNS bytea /* alloc::vec::Vec<u8> */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_send_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:98
-- vchord::datatype::operators_scalar8::_vchord_scalar8_sphere_cosine_in
CREATE  FUNCTION "_vchord_scalar8_sphere_cosine_in"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" sphere_scalar8 /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_sphere_cosine_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:50
-- vchord::datatype::operators_scalar8::_vchord_scalar8_sphere_ip_in
CREATE  FUNCTION "_vchord_scalar8_sphere_ip_in"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" sphere_scalar8 /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_sphere_ip_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_scalar8.rs:74
-- vchord::datatype::operators_scalar8::_vchord_scalar8_sphere_l2_in
CREATE  FUNCTION "_vchord_scalar8_sphere_l2_in"(
    "lhs" scalar8, /* vchord::datatype::memory_scalar8::Scalar8Input */
    "rhs" sphere_scalar8 /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_scalar8_sphere_l2_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/typmod.rs:58
-- vchord::datatype::typmod::_vchord_typmod_in_65535
CREATE  FUNCTION "_vchord_typmod_in_65535"(
    "list" cstring[] /* pgrx::datum::array::Array<&core::ffi::c_str::CStr> */
) RETURNS INT /* i32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_typmod_in_65535_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/typmod.rs:76
-- vchord::datatype::typmod::_vchord_typmod_out
CREATE  FUNCTION "_vchord_typmod_out"(
    "typmod" INT /* i32 */
) RETURNS cstring /* alloc::ffi::c_str::CString */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_typmod_out_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_vector.rs:93
-- vchord::datatype::operators_vector::_vchord_vector_operator_maxsim
CREATE  FUNCTION "_vchord_vector_operator_maxsim"(
    "lhs" vector[], /* pgrx::datum::array::Array<vchord::datatype::memory_vector::VectorInput> */
    "rhs" vector[] /* pgrx::datum::array::Array<vchord::datatype::memory_vector::VectorInput> */
) RETURNS real /* f32 */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_vector_operator_maxsim_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/functions_scalar8.rs:21
-- vchord::datatype::functions_scalar8::_vchord_vector_quantize_to_scalar8
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_vector.rs:69
-- vchord::datatype::operators_vector::_vchord_vector_sphere_cosine_in
CREATE  FUNCTION "_vchord_vector_sphere_cosine_in"(
    "lhs" vector, /* vchord::datatype::memory_vector::VectorInput */
    "rhs" sphere_vector /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_vector_sphere_cosine_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_vector.rs:45
-- vchord::datatype::operators_vector::_vchord_vector_sphere_ip_in
CREATE  FUNCTION "_vchord_vector_sphere_ip_in"(
    "lhs" vector, /* vchord::datatype::memory_vector::VectorInput */
    "rhs" sphere_vector /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_vector_sphere_ip_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/datatype/operators_vector.rs:21
-- vchord::datatype::operators_vector::_vchord_vector_sphere_l2_in
CREATE  FUNCTION "_vchord_vector_sphere_l2_in"(
    "lhs" vector, /* vchord::datatype::memory_vector::VectorInput */
    "rhs" sphere_vector /* pgrx::heap_tuple::PgHeapTuple<pgrx::pgbox::AllocatedByRust> */
) RETURNS bool /* bool */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchord_vector_sphere_l2_in_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/vchordg/am/mod.rs:78
-- vchord::index::vchordg::am::_vchordg_amhandler
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/functions.rs:21
-- vchord::index::functions::_vchordg_prewarm
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:35
-- vchord::index::opclass::_vchordg_support_halfvec_cosine_ops
CREATE  FUNCTION "_vchordg_support_halfvec_cosine_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_halfvec_cosine_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:40
-- vchord::index::opclass::_vchordg_support_halfvec_ip_ops
CREATE  FUNCTION "_vchordg_support_halfvec_ip_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_halfvec_ip_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:30
-- vchord::index::opclass::_vchordg_support_halfvec_l2_ops
CREATE  FUNCTION "_vchordg_support_halfvec_l2_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_halfvec_l2_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:20
-- vchord::index::opclass::_vchordg_support_vector_cosine_ops
CREATE  FUNCTION "_vchordg_support_vector_cosine_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_vector_cosine_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:25
-- vchord::index::opclass::_vchordg_support_vector_ip_ops
CREATE  FUNCTION "_vchordg_support_vector_ip_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_vector_ip_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:15
-- vchord::index::opclass::_vchordg_support_vector_l2_ops
CREATE  FUNCTION "_vchordg_support_vector_l2_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordg_support_vector_l2_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/vchordrq/am/mod.rs:80
-- vchord::index::vchordrq::am::_vchordrq_amhandler
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/functions.rs:43
-- vchord::index::functions::_vchordrq_prewarm
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/functions.rs:90
-- vchord::index::functions::_vchordrq_sampled_values
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:70
-- vchord::index::opclass::_vchordrq_support_halfvec_cosine_ops
CREATE  FUNCTION "_vchordrq_support_halfvec_cosine_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_halfvec_cosine_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:65
-- vchord::index::opclass::_vchordrq_support_halfvec_ip_ops
CREATE  FUNCTION "_vchordrq_support_halfvec_ip_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_halfvec_ip_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:60
-- vchord::index::opclass::_vchordrq_support_halfvec_l2_ops
CREATE  FUNCTION "_vchordrq_support_halfvec_l2_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_halfvec_l2_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:80
-- vchord::index::opclass::_vchordrq_support_halfvec_maxsim_ops
CREATE  FUNCTION "_vchordrq_support_halfvec_maxsim_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_halfvec_maxsim_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:55
-- vchord::index::opclass::_vchordrq_support_vector_cosine_ops
CREATE  FUNCTION "_vchordrq_support_vector_cosine_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_vector_cosine_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:50
-- vchord::index::opclass::_vchordrq_support_vector_ip_ops
CREATE  FUNCTION "_vchordrq_support_vector_ip_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_vector_ip_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:45
-- vchord::index::opclass::_vchordrq_support_vector_l2_ops
CREATE  FUNCTION "_vchordrq_support_vector_l2_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_vector_l2_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/index/opclass.rs:75
-- vchord::index::opclass::_vchordrq_support_vector_maxsim_ops
CREATE  FUNCTION "_vchordrq_support_vector_maxsim_ops"() RETURNS TEXT /* alloc::string::String */
IMMUTABLE STRICT PARALLEL SAFE
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', '_vchordrq_support_vector_maxsim_ops_wrapper';
/* </end connected objects> */

/* <begin connected objects> */
-- src/lib.rs:47
-- finalize
-- List of data types

CREATE TYPE scalar8 (
    INPUT = _vchord_scalar8_in,
    OUTPUT = _vchord_scalar8_out,
    RECEIVE = _vchord_scalar8_recv,
    SEND = _vchord_scalar8_send,
    TYPMOD_IN = _vchord_typmod_in_65535,
    TYPMOD_OUT = _vchord_typmod_out,
    STORAGE = EXTERNAL,
    INTERNALLENGTH = VARIABLE,
    ALIGNMENT = double
);

CREATE TYPE sphere_vector AS (
    center vector,
    radius REAL
);

CREATE TYPE sphere_halfvec AS (
    center halfvec,
    radius REAL
);

CREATE TYPE sphere_scalar8 AS (
    center scalar8,
    radius REAL
);

-- List of operators

CREATE OPERATOR <-> (
    PROCEDURE = _vchord_scalar8_operator_l2,
    LEFTARG = scalar8,
    RIGHTARG = scalar8,
    COMMUTATOR = <->
);

CREATE OPERATOR <#> (
    PROCEDURE = _vchord_scalar8_operator_ip,
    LEFTARG = scalar8,
    RIGHTARG = scalar8,
    COMMUTATOR = <#>
);

CREATE OPERATOR <=> (
    PROCEDURE = _vchord_scalar8_operator_cosine,
    LEFTARG = scalar8,
    RIGHTARG = scalar8,
    COMMUTATOR = <=>
);

CREATE OPERATOR <<->> (
    PROCEDURE = _vchord_vector_sphere_l2_in,
    LEFTARG = vector,
    RIGHTARG = sphere_vector,
    COMMUTATOR = <<->>
);

CREATE OPERATOR <<->> (
    PROCEDURE = _vchord_halfvec_sphere_l2_in,
    LEFTARG = halfvec,
    RIGHTARG = sphere_halfvec,
    COMMUTATOR = <<->>
);

CREATE OPERATOR <<->> (
    PROCEDURE = _vchord_scalar8_sphere_l2_in,
    LEFTARG = scalar8,
    RIGHTARG = sphere_scalar8,
    COMMUTATOR = <<->>
);

CREATE OPERATOR <<#>> (
    PROCEDURE = _vchord_vector_sphere_ip_in,
    LEFTARG = vector,
    RIGHTARG = sphere_vector,
    COMMUTATOR = <<#>>
);

CREATE OPERATOR <<#>> (
    PROCEDURE = _vchord_halfvec_sphere_ip_in,
    LEFTARG = halfvec,
    RIGHTARG = sphere_halfvec,
    COMMUTATOR = <<#>>
);

CREATE OPERATOR <<#>> (
    PROCEDURE = _vchord_scalar8_sphere_ip_in,
    LEFTARG = scalar8,
    RIGHTARG = sphere_scalar8,
    COMMUTATOR = <<#>>
);

CREATE OPERATOR <<=>> (
    PROCEDURE = _vchord_vector_sphere_cosine_in,
    LEFTARG = vector,
    RIGHTARG = sphere_vector,
    COMMUTATOR = <<=>>
);

CREATE OPERATOR <<=>> (
    PROCEDURE = _vchord_halfvec_sphere_cosine_in,
    LEFTARG = halfvec,
    RIGHTARG = sphere_halfvec,
    COMMUTATOR = <<=>>
);

CREATE OPERATOR <<=>> (
    PROCEDURE = _vchord_scalar8_sphere_cosine_in,
    LEFTARG = scalar8,
    RIGHTARG = sphere_scalar8,
    COMMUTATOR = <<=>>
);

CREATE OPERATOR @# (
    PROCEDURE = _vchord_vector_operator_maxsim,
    LEFTARG = vector[],
    RIGHTARG = vector[]
);

CREATE OPERATOR @# (
    PROCEDURE = _vchord_halfvec_operator_maxsim,
    LEFTARG = halfvec[],
    RIGHTARG = halfvec[]
);

-- List of functions

CREATE FUNCTION sphere(vector, real) RETURNS sphere_vector
IMMUTABLE PARALLEL SAFE LANGUAGE sql AS 'SELECT ROW($1, $2)';

CREATE FUNCTION sphere(halfvec, real) RETURNS sphere_halfvec
IMMUTABLE PARALLEL SAFE LANGUAGE sql AS 'SELECT ROW($1, $2)';

CREATE FUNCTION sphere(scalar8, real) RETURNS sphere_scalar8
IMMUTABLE PARALLEL SAFE LANGUAGE sql AS 'SELECT ROW($1, $2)';

CREATE FUNCTION quantize_to_scalar8(vector) RETURNS scalar8
IMMUTABLE STRICT PARALLEL SAFE LANGUAGE c AS 'MODULE_PATHNAME', '_vchord_vector_quantize_to_scalar8_wrapper';

CREATE FUNCTION quantize_to_scalar8(halfvec) RETURNS scalar8
IMMUTABLE STRICT PARALLEL SAFE LANGUAGE c AS 'MODULE_PATHNAME', '_vchord_halfvec_quantize_to_scalar8_wrapper';

CREATE FUNCTION vchordrq_sampled_values(regclass) RETURNS SETOF TEXT
STRICT LANGUAGE c AS 'MODULE_PATHNAME', '_vchordrq_sampled_values_wrapper';

CREATE FUNCTION vchordrq_sampled_queries(regclass)
RETURNS TABLE(
    schema_name NAME,
    index_name NAME,
    table_name NAME,
    column_name NAME,
    operator NAME,
    value TEXT
)
STRICT LANGUAGE plpgsql AS $$
DECLARE
    ext_schema TEXT;
    query_text TEXT;
BEGIN
    SELECT n.nspname
    INTO ext_schema
    FROM pg_catalog.pg_extension e
    JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
    WHERE e.extname = 'vchord';

    IF ext_schema IS NULL THEN
        RAISE EXCEPTION 'vchord is not installed';
    END IF;

    query_text := format(
        $q$
        WITH index_metadata AS (
            SELECT
                NS.nspname AS schema_name,
                I.relname AS index_name,
                C.relname AS table_name,
                PA.attname AS column_name,
                OP.oprname AS operator
            FROM
                pg_catalog.pg_index X
            JOIN
                pg_catalog.pg_class C ON C.oid = X.indrelid
            JOIN
                pg_catalog.pg_namespace NS ON C.relnamespace = NS.oid
            JOIN
                pg_catalog.pg_class I ON I.oid = X.indexrelid
            JOIN
                pg_catalog.pg_am A ON A.oid = I.relam
            LEFT JOIN
                pg_catalog.pg_opclass AS OPC ON OPC.oid = X.indclass[0]
            LEFT JOIN
                pg_catalog.pg_amop AO ON OPC.opcfamily = AO.amopfamily
            LEFT JOIN
                pg_catalog.pg_operator OP ON OP.oid = AO.amopopr
            LEFT JOIN
                pg_catalog.pg_attribute PA ON PA.attrelid = X.indrelid AND PA.attnum = X.indkey[0]
            WHERE
                A.amname = 'vchordrq'
                AND AO.amopstrategy = 1
                AND C.relkind = 'r'
                AND X.indnatts = 1
                AND X.indexrelid = %1$s
        )
        SELECT
            im.schema_name,
            im.index_name,
            im.table_name,
            im.column_name,
            im.operator,
            s.value
        FROM
            index_metadata im,
            LATERAL %2$I.vchordrq_sampled_values(%1$s) AS s(value);
        $q$,
        $1::oid,
        ext_schema
    );
    RETURN QUERY EXECUTE query_text;
END;
$$;

CREATE FUNCTION vchordrq_amhandler(internal) RETURNS index_am_handler
IMMUTABLE STRICT PARALLEL SAFE LANGUAGE c AS 'MODULE_PATHNAME', '_vchordrq_amhandler_wrapper';

CREATE FUNCTION vchordrq_prewarm(regclass, integer default 0) RETURNS TEXT
STRICT LANGUAGE c AS 'MODULE_PATHNAME', '_vchordrq_prewarm_wrapper';

CREATE FUNCTION vchordrq_evaluate_query_recall(
    query text,
    exact_search boolean default false,
    accu_probes TEXT default NULL,
    accu_epsilon real default 1.9
)
RETURNS real
LANGUAGE plpgsql
AS $$
DECLARE
    rough tid[];
    accu tid[];
    match_count integer := 0;
    accu_k integer;
    recall real;
    rough_probes text;
BEGIN
    IF query IS NULL OR exact_search IS NULL OR accu_epsilon IS NULL THEN
        RETURN NULL;
    END IF;
    IF query LIKE '%@#%' AND NOT exact_search THEN
        RAISE EXCEPTION 'MaxSim operator cannot be used for estimated recall evaluation. Please use exact_search => true.';
    END IF;
    IF NOT exact_search THEN
        BEGIN
            rough_probes := current_setting('vchordrq.probes');
        END;
    END IF;

    BEGIN
        EXECUTE
            format('SELECT coalesce(array_agg(id), array[]::tid[]) FROM (%s) AS result(id)', query)
        INTO
            rough;
    EXCEPTION WHEN OTHERS THEN
        RAISE EXCEPTION 'Error executing ANN query "%": %', query, SQLERRM;
    END;

    BEGIN
        IF exact_search THEN
            SET LOCAL vchordrq.enable_scan = off;
        ELSE
            IF accu_probes IS NULL THEN
                IF rough_probes = '' THEN
                    accu_probes := '';
                ELSIF position(',' in rough_probes) > 0 THEN
                    accu_probes := '65535,65535';
                ELSE
                    accu_probes := '65535';
                END IF;
            END IF;
            EXECUTE format('SET LOCAL "vchordrq.probes" = %L', accu_probes);
            EXECUTE format('SET LOCAL "vchordrq.epsilon" = %L', accu_epsilon);
            SET LOCAL vchordrq.max_scan_tuples = -1;
        END IF;
        EXECUTE
            format('SELECT coalesce(array_agg(id), array[]::tid[]) FROM (%s) AS result(id)', query)
        INTO
            accu;
    EXCEPTION WHEN OTHERS THEN
         RAISE EXCEPTION 'Error executing Ground Truth query "%": %', query, SQLERRM;
    END;
    accu_k := cardinality(accu);
    IF accu_k = 0 THEN
        RAISE WARNING  'Query "%": No results found, returning NaN for recall.', query;
        RETURN 'NaN';
    END IF;
    SELECT COUNT(*) INTO match_count FROM (SELECT unnest(rough) INTERSECT SELECT unnest(accu)) AS tids;
    recall := match_count::real / accu_k::real;
    RETURN recall;
END;
$$;

CREATE FUNCTION vchordg_amhandler(internal) RETURNS index_am_handler
IMMUTABLE STRICT PARALLEL SAFE LANGUAGE c AS 'MODULE_PATHNAME', '_vchordg_amhandler_wrapper';

CREATE FUNCTION vchordg_prewarm(regclass) RETURNS TEXT
STRICT LANGUAGE c AS 'MODULE_PATHNAME', '_vchordg_prewarm_wrapper';

-- List of access methods

CREATE ACCESS METHOD vchordrq TYPE INDEX HANDLER vchordrq_amhandler;
CREATE ACCESS METHOD vchordg TYPE INDEX HANDLER vchordg_amhandler;

-- List of operator families

CREATE OPERATOR FAMILY vector_l2_ops USING vchordrq;
CREATE OPERATOR FAMILY vector_ip_ops USING vchordrq;
CREATE OPERATOR FAMILY vector_cosine_ops USING vchordrq;
CREATE OPERATOR FAMILY halfvec_l2_ops USING vchordrq;
CREATE OPERATOR FAMILY halfvec_ip_ops USING vchordrq;
CREATE OPERATOR FAMILY halfvec_cosine_ops USING vchordrq;
CREATE OPERATOR FAMILY vector_maxsim_ops USING vchordrq;
CREATE OPERATOR FAMILY halfvec_maxsim_ops USING vchordrq;
CREATE OPERATOR FAMILY vector_l2_ops USING vchordg;
CREATE OPERATOR FAMILY vector_ip_ops USING vchordg;
CREATE OPERATOR FAMILY vector_cosine_ops USING vchordg;
CREATE OPERATOR FAMILY halfvec_l2_ops USING vchordg;
CREATE OPERATOR FAMILY halfvec_ip_ops USING vchordg;
CREATE OPERATOR FAMILY halfvec_cosine_ops USING vchordg;

-- List of operator classes

CREATE OPERATOR CLASS vector_l2_ops
    FOR TYPE vector USING vchordrq FAMILY vector_l2_ops AS
    OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<->> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_vector_l2_ops();

CREATE OPERATOR CLASS vector_ip_ops
    FOR TYPE vector USING vchordrq FAMILY vector_ip_ops AS
    OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<#>> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_vector_ip_ops();

CREATE OPERATOR CLASS vector_cosine_ops
    FOR TYPE vector USING vchordrq FAMILY vector_cosine_ops AS
    OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<=>> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_vector_cosine_ops();

CREATE OPERATOR CLASS halfvec_l2_ops
    FOR TYPE halfvec USING vchordrq FAMILY halfvec_l2_ops AS
    OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<->> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_halfvec_l2_ops();

CREATE OPERATOR CLASS halfvec_ip_ops
    FOR TYPE halfvec USING vchordrq FAMILY halfvec_ip_ops AS
    OPERATOR 1 <#> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<#>> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_halfvec_ip_ops();

CREATE OPERATOR CLASS halfvec_cosine_ops
    FOR TYPE halfvec USING vchordrq FAMILY halfvec_cosine_ops AS
    OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<=>> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordrq_support_halfvec_cosine_ops();

CREATE OPERATOR CLASS vector_maxsim_ops
    FOR TYPE vector[] USING vchordrq FAMILY vector_maxsim_ops AS
    OPERATOR 3 @# (vector[], vector[]) FOR ORDER BY float_ops,
    FUNCTION 1 _vchordrq_support_vector_maxsim_ops();

CREATE OPERATOR CLASS halfvec_maxsim_ops
    FOR TYPE halfvec[] USING vchordrq FAMILY halfvec_maxsim_ops AS
    OPERATOR 3 @# (halfvec[], halfvec[]) FOR ORDER BY float_ops,
    FUNCTION 1 _vchordrq_support_halfvec_maxsim_ops();

CREATE OPERATOR CLASS vector_l2_ops
    FOR TYPE vector USING vchordg FAMILY vector_l2_ops AS
    OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<->> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordg_support_vector_l2_ops();

CREATE OPERATOR CLASS vector_ip_ops
    FOR TYPE vector USING vchordg FAMILY vector_ip_ops AS
    OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<#>> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordg_support_vector_ip_ops();

CREATE OPERATOR CLASS vector_cosine_ops
    FOR TYPE vector USING vchordg FAMILY vector_cosine_ops AS
    OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops,
    OPERATOR 2 <<=>> (vector, sphere_vector) FOR SEARCH,
    FUNCTION 1 _vchordg_support_vector_cosine_ops();

CREATE OPERATOR CLASS halfvec_l2_ops
    FOR TYPE halfvec USING vchordg FAMILY halfvec_l2_ops AS
    OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<->> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordg_support_halfvec_l2_ops();

CREATE OPERATOR CLASS halfvec_ip_ops
    FOR TYPE halfvec USING vchordg FAMILY halfvec_ip_ops AS
    OPERATOR 1 <#> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<#>> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordg_support_halfvec_ip_ops();

CREATE OPERATOR CLASS halfvec_cosine_ops
    FOR TYPE halfvec USING vchordg FAMILY halfvec_cosine_ops AS
    OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops,
    OPERATOR 2 <<=>> (halfvec, sphere_halfvec) FOR SEARCH,
    FUNCTION 1 _vchordg_support_halfvec_cosine_ops();

-- List of views

CREATE VIEW vchordrq_sampled_queries AS
SELECT
    record.schema_name,
    record.index_name,
    record.table_name,
    record.column_name,
    record.operator,
    record.value
FROM
    (
        SELECT i.oid
        FROM pg_catalog.pg_class AS i
        JOIN pg_catalog.pg_index AS ix ON i.oid = ix.indexrelid
        JOIN pg_catalog.pg_opclass AS opc ON ix.indclass[0] = opc.oid
        JOIN pg_catalog.pg_am AS am ON opc.opcmethod = am.oid
        WHERE am.amname = 'vchordrq'
    ) AS index_oids
CROSS JOIN LATERAL vchordrq_sampled_queries(index_oids.oid::regclass) AS record;
/* </end connected objects> */

