-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathpase--0.0.1.sql
175 lines (149 loc) · 5.74 KB
/
pase--0.0.1.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
-- Create the user-defined type for N-dimensional boxes
CREATE FUNCTION pase_in(cstring)
RETURNS pase
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION pase_out(pase)
RETURNS cstring
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION pase_recv(internal)
RETURNS pase
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION pase_send(pase)
RETURNS bytea
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE TYPE pase (
INTERNALLENGTH = variable,
INPUT = pase_in,
OUTPUT = pase_out,
RECEIVE = pase_recv,
SEND = pase_send,
ALIGNMENT = float
);
-- pase constructor[vectors, extra data, distance type(l2 or ip)]
CREATE FUNCTION pase(float4[], int DEFAULT 0, int DEFAULT 0)
RETURNS pase
AS 'MODULE_PATHNAME', 'pase_f4_i_i'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- pase constructor[text vectors, extra data, distance type(l2 or ip)]
CREATE FUNCTION pase(text, int DEFAULT 0, int DEFAULT 0)
RETURNS pase
AS 'MODULE_PATHNAME', 'pase_text_i_i'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- distance function
CREATE FUNCTION g_pase_distance(float4[], pase)
RETURNS float4
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION g_pase_distance_3(text, pase)
RETURNS float4
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- operator on pase
CREATE OPERATOR <?> (
LEFTARG = float4[], RIGHTARG = pase, PROCEDURE = g_pase_distance,
COMMUTATOR = '<?>'
);
CREATE OPERATOR <#> (
LEFTARG = float4[], RIGHTARG = pase, PROCEDURE = g_pase_distance,
COMMUTATOR = '<#>'
);
CREATE OPERATOR <!> (
LEFTARG = text, RIGHTARG = pase, PROCEDURE = g_pase_distance_3,
COMMUTATOR = '<!>'
);
-- hnsw index
CREATE FUNCTION pase_hnsw(internal)
RETURNS index_am_handler
AS 'MODULE_PATHNAME'
LANGUAGE C;
CREATE ACCESS METHOD pase_hnsw TYPE INDEX HANDLER pase_hnsw;
CREATE OPERATOR CLASS pase_hnsw_ops
DEFAULT FOR TYPE float4[] USING pase_hnsw AS
OPERATOR 1 <?> (float4[], pase) FOR ORDER BY float_ops;
CREATE OPERATOR CLASS pase_hnsw_text_ops
DEFAULT FOR TYPE text USING pase_hnsw AS
OPERATOR 1 <!> (text, pase) FOR ORDER BY float_ops;
-- ivfflat index
CREATE FUNCTION pase_ivfflat(internal)
RETURNS index_am_handler
AS 'MODULE_PATHNAME'
LANGUAGE C;
CREATE ACCESS METHOD pase_ivfflat TYPE INDEX HANDLER pase_ivfflat;
CREATE OPERATOR CLASS pase_ivfflat_float_ops
DEFAULT FOR TYPE float4[] USING pase_ivfflat AS
OPERATOR 1 <#> (float4[], pase) FOR ORDER BY float_ops;
CREATE OPERATOR CLASS pase_ivfflat_text_ops
DEFAULT FOR TYPE text USING pase_ivfflat AS
OPERATOR 1 <!> (text, pase) FOR ORDER BY float_ops;
SET enable_seqscan=off;
SET enable_indexscan=on;
CREATE OR REPLACE FUNCTION ivfflat_search(query_vector text, k integer, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', 5, 0) AS distance FROM %s ORDER BY vector <!> pase(''%s'', 5, 0) ASC LIMIT %s;
', query_vector, table_name, query_vector, k);
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION ivfflat_search(query_vector text, k integer, cr integer, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', %s, 0) AS distance FROM %s ORDER BY vector <!> pase(''%s'', %s, 0) ASC LIMIT %s;
', query_vector, cr, table_name, query_vector, cr, k);
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION ivfflat_search(query_vector text, k integer, cr integer, query text, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
IF query != '' THEN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', %s, 0) AS distance FROM %s WHERE %s ORDER BY vector <!> pase(''%s'', %s, 0) ASC LIMIT %s;
', query_vector, cr, table_name, query, query_vector, cr, k);
ELSE
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', %s, 0) AS distance FROM %s ORDER BY vector <!> pase(''%s'', %s, 0) ASC LIMIT %s;
', query_vector, cr, table_name, query_vector, cr, k);
END IF;
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION ivfflat_search(query_vector text, k integer, query text, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
IF query != '' THEN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', 5, 0) AS distance FROM %s WHERE %s ORDER BY vector <!> pase(''%s'', 5, 0) ASC LIMIT %s;
', query_vector, table_name, query, query_vector, k);
ELSE
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', 5, 0) AS distance FROM %s ORDER BY vector <!> pase(''%s'', 5, 0) ASC LIMIT %s;
', query_vector, table_name, query_vector, k);
END IF;
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION hnsw_search(query_vector text, ef integer, k integer, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'', %s) AS distance FROM %s ORDER BY vector <!> pase(''%s'', %s) ASC LIMIT %s;
', query_vector, ef, table_name, query_vector, ef, k);
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION hnsw_search(query_vector text, query text, table_name text) RETURNS TABLE (id text, distance float4) AS $$
BEGIN
IF query != '' THEN
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'') AS distance FROM %s WHERE %s ORDER BY distance ASC LIMIT %s;
', query_vector, table_name, query, k);
ELSE
RETURN QUERY EXECUTE format('
SELECT id, vector <!> pase(''%s'') AS distance FROM %s ORDER BY vector <!> pase(''%s'') ASC LIMIT %s;
', query_vector, table_name, query_vector, k);
END IF;
END
$$
LANGUAGE plpgsql;