Skip to content

Commit 6380073

Browse files
craig[bot]DrewKimball
andcommitted
Merge #144533
144533: sql/vecindex: support operator class and index type syntax r=mw5h a=DrewKimball #### sql/vecindex: ability to specify distance functions for index creation This commit adds support for specifying the operator class for a vector index (e.g. `vector_l2_ops`, `vector_cosine_ops` etc.). Currently, only `vector_l2_ops` is supported. It is also the default option, which means that users can omit the operator class in index definitions. Fixes #143110 Release note (sql change): It is now possible to specify the operator class for a vector index, although only `vector_l2_ops` is supported for now. In addition, `vector_l2_ops` is the default, so it is possible to omit the operator class from an index definition. #### sql/vecindex: make hnsw alias for cspann for index creation This commit adds `hnsw` to the accepted list of index types when a vector index is defined using the `USING` syntax. However, we will silently provide a `cspann` index instead. This change is made in anticipation of third-party tools that want to use `cspann`. Fixes #143109 Release note (sql change): When creating a vector index via the `USING` syntax, is is now possible to specify `hnsw` as the index type, although a `cspann` vector index will still be provided. The goal of this change is to increase compatibility with third-party tools. Co-authored-by: Drew Kimball <[email protected]>
2 parents 692b93c + b269a74 commit 6380073

File tree

20 files changed

+174
-88
lines changed

20 files changed

+174
-88
lines changed

pkg/ccl/logictestccl/testdata/logic_test/partitioning_index

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ SHOW CREATE TABLE vector
206206
b INT8 NULL,
207207
v VECTOR(3) NULL,
208208
CONSTRAINT vector_pkey PRIMARY KEY (a ASC),
209-
VECTOR INDEX vector_b_v_idx (b ASC, v) PARTITION BY LIST (b) (
209+
VECTOR INDEX vector_b_v_idx (b ASC, v vector_l2_ops) PARTITION BY LIST (b) (
210210
PARTITION p1 VALUES IN ((1)),
211211
PARTITION pu VALUES IN ((NULL))
212212
),
213-
VECTOR INDEX vector_idx (a ASC, b ASC, v) PARTITION BY LIST (a, b) (
213+
VECTOR INDEX vector_idx (a ASC, b ASC, v vector_l2_ops) PARTITION BY LIST (a, b) (
214214
PARTITION p1 VALUES IN ((1, 1), (2, 2))
215215
)
216216
)

pkg/cmd/roachtest/testdata/pg_regress/btree_index.diffs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/btree_index.out -
8686
-- "lost".
8787
--
8888
CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops);
89-
+ERROR: operator classes are only allowed for the last column of an inverted index
89+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
9090
CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops);
91-
+ERROR: operator classes are only allowed for the last column of an inverted index
91+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
9292
CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops);
93-
+ERROR: operator classes are only allowed for the last column of an inverted index
93+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
9494
CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops);
95-
+ERROR: operator classes are only allowed for the last column of an inverted index
95+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
9696
--
9797
-- test retrieval of min/max keys for each index
9898
--

pkg/cmd/roachtest/testdata/pg_regress/create_index.diffs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/create_index.out
1010
-- BTREE
1111
--
1212
CREATE INDEX onek_unique1 ON onek USING btree(unique1 int4_ops);
13-
+ERROR: operator classes are only allowed for the last column of an inverted index
13+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
1414
CREATE INDEX IF NOT EXISTS onek_unique1 ON onek USING btree(unique1 int4_ops);
1515
-NOTICE: relation "onek_unique1" already exists, skipping
16-
+ERROR: operator classes are only allowed for the last column of an inverted index
16+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
1717
CREATE INDEX IF NOT EXISTS ON onek USING btree(unique1 int4_ops);
1818
-ERROR: syntax error at or near "ON"
1919
-LINE 1: CREATE INDEX IF NOT EXISTS ON onek USING btree(unique1 int4_...
@@ -24,24 +24,24 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/create_index.out
2424
+ ^
2525
+HINT: try \h CREATE INDEX
2626
CREATE INDEX onek_unique2 ON onek USING btree(unique2 int4_ops);
27-
+ERROR: operator classes are only allowed for the last column of an inverted index
27+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
2828
CREATE INDEX onek_hundred ON onek USING btree(hundred int4_ops);
29-
+ERROR: operator classes are only allowed for the last column of an inverted index
29+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3030
CREATE INDEX onek_stringu1 ON onek USING btree(stringu1 name_ops);
31-
+ERROR: operator classes are only allowed for the last column of an inverted index
31+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3232
CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops);
33-
+ERROR: operator classes are only allowed for the last column of an inverted index
33+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3434
CREATE INDEX tenk1_unique2 ON tenk1 USING btree(unique2 int4_ops);
35-
+ERROR: operator classes are only allowed for the last column of an inverted index
35+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3636
CREATE INDEX tenk1_hundred ON tenk1 USING btree(hundred int4_ops);
37-
+ERROR: operator classes are only allowed for the last column of an inverted index
37+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3838
CREATE INDEX tenk1_thous_tenthous ON tenk1 (thousand, tenthous);
3939
CREATE INDEX tenk2_unique1 ON tenk2 USING btree(unique1 int4_ops);
40-
+ERROR: operator classes are only allowed for the last column of an inverted index
40+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
4141
CREATE INDEX tenk2_unique2 ON tenk2 USING btree(unique2 int4_ops);
42-
+ERROR: operator classes are only allowed for the last column of an inverted index
42+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
4343
CREATE INDEX tenk2_hundred ON tenk2 USING btree(hundred int4_ops);
44-
+ERROR: operator classes are only allowed for the last column of an inverted index
44+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
4545
CREATE INDEX rix ON road USING btree (name text_ops);
4646
+ERROR: relation "road" does not exist
4747
CREATE INDEX iix ON ihighway USING btree (name text_ops);
@@ -61,13 +61,13 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/create_index.out
6161
--
6262
CREATE INDEX onek2_u1_prtl ON onek2 USING btree(unique1 int4_ops)
6363
where unique1 < 20 or unique1 > 980;
64-
+ERROR: operator classes are only allowed for the last column of an inverted index
64+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
6565
CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops)
6666
where stringu1 < 'B';
67-
+ERROR: operator classes are only allowed for the last column of an inverted index
67+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
6868
CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
6969
where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K';
70-
+ERROR: operator classes are only allowed for the last column of an inverted index
70+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
7171
--
7272
-- GiST (rtree-equivalent opclasses only)
7373
--
@@ -2086,7 +2086,7 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/create_index.out
20862086
DROP TABLE func_index_heap;
20872087
CREATE TABLE func_index_heap (f1 text, f2 text);
20882088
CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops);
2089-
+ERROR: operator classes are only allowed for the last column of an inverted index
2089+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
20902090
INSERT INTO func_index_heap VALUES('ABC','DEF');
20912091
INSERT INTO func_index_heap VALUES('AB','CDEFG');
20922092
INSERT INTO func_index_heap VALUES('QWE','RTY');

pkg/cmd/roachtest/testdata/pg_regress/insert_conflict.diffs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/insert_conflict.o
55
-- named collations
66
--
77
create unique index op_index_key on insertconflicttest(key, fruit text_pattern_ops);
8-
+ERROR: operator classes are only allowed for the last column of an inverted index
8+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
99
create unique index collation_index_key on insertconflicttest(key, fruit collate "C");
1010
+ERROR: at or near "collate": syntax error
1111
+DETAIL: source SQL:

pkg/cmd/roachtest/testdata/pg_regress/plpgsql.diffs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,75 +5,75 @@ diff -U3 --label=/mnt/data1/postgres/src/test/regress/expected/plpgsql.out --lab
55
comment text
66
);
77
create unique index Room_rno on Room using btree (roomno bpchar_ops);
8-
+ERROR: operator classes are only allowed for the last column of an inverted index
8+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
99
create table WSlot (
1010
slotname char(20),
1111
roomno char(8),
1212
@@ -32,11 +33,13 @@
1313
backlink char(20)
1414
);
1515
create unique index WSlot_name on WSlot using btree (slotname bpchar_ops);
16-
+ERROR: operator classes are only allowed for the last column of an inverted index
16+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
1717
create table PField (
1818
name text,
1919
comment text
2020
);
2121
create unique index PField_name on PField using btree (name text_ops);
22-
+ERROR: operator classes are only allowed for the last column of an inverted index
22+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
2323
create table PSlot (
2424
slotname char(20),
2525
pfname text,
2626
@@ -44,6 +47,7 @@
2727
backlink char(20)
2828
);
2929
create unique index PSlot_name on PSlot using btree (slotname bpchar_ops);
30-
+ERROR: operator classes are only allowed for the last column of an inverted index
30+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3131
create table PLine (
3232
slotname char(20),
3333
phonenumber char(20),
3434
@@ -51,12 +55,14 @@
3535
backlink char(20)
3636
);
3737
create unique index PLine_name on PLine using btree (slotname bpchar_ops);
38-
+ERROR: operator classes are only allowed for the last column of an inverted index
38+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
3939
create table Hub (
4040
name char(14),
4141
comment text,
4242
nslots integer
4343
);
4444
create unique index Hub_name on Hub using btree (name bpchar_ops);
45-
+ERROR: operator classes are only allowed for the last column of an inverted index
45+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
4646
create table HSlot (
4747
slotname char(20),
4848
hubname char(14),
4949
@@ -64,12 +70,15 @@
5050
slotlink char(20)
5151
);
5252
create unique index HSlot_name on HSlot using btree (slotname bpchar_ops);
53-
+ERROR: operator classes are only allowed for the last column of an inverted index
53+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
5454
create index HSlot_hubname on HSlot using btree (hubname bpchar_ops);
55-
+ERROR: operator classes are only allowed for the last column of an inverted index
55+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
5656
create table System (
5757
name text,
5858
comment text
5959
);
6060
create unique index System_name on System using btree (name text_ops);
61-
+ERROR: operator classes are only allowed for the last column of an inverted index
61+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
6262
create table IFace (
6363
slotname char(20),
6464
sysname text,
6565
@@ -77,12 +86,14 @@
6666
slotlink char(20)
6767
);
6868
create unique index IFace_name on IFace using btree (slotname bpchar_ops);
69-
+ERROR: operator classes are only allowed for the last column of an inverted index
69+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
7070
create table PHone (
7171
slotname char(20),
7272
comment text,
7373
slotlink char(20)
7474
);
7575
create unique index PHone_name on PHone using btree (slotname bpchar_ops);
76-
+ERROR: operator classes are only allowed for the last column of an inverted index
76+
+ERROR: operator classes are only allowed for the last column of an inverted or vector index
7777
-- ************************************************************
7878
-- *
7979
-- * Trigger procedures and functions for the patchfield

pkg/sql/catalog/catformat/index.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,19 @@ func FormatIndexElements(
248248
} else {
249249
f.FormatNameP(&index.KeyColumnNames[i])
250250
}
251-
// TODO(drewk): we might need to print something like "vector_l2_ops" for
252-
// vector indexes.
253-
if index.Type == idxtype.INVERTED &&
254-
col.GetID() == index.InvertedColumnID() && len(index.InvertedColumnKinds) > 0 {
255-
switch index.InvertedColumnKinds[0] {
256-
case catpb.InvertedIndexColumnKind_TRIGRAM:
257-
f.WriteString(" gin_trgm_ops")
251+
switch index.Type {
252+
case idxtype.INVERTED:
253+
if col.GetID() == index.InvertedColumnID() && len(index.InvertedColumnKinds) > 0 {
254+
switch index.InvertedColumnKinds[0] {
255+
case catpb.InvertedIndexColumnKind_TRIGRAM:
256+
f.WriteString(" gin_trgm_ops")
257+
}
258+
}
259+
case idxtype.VECTOR:
260+
// TODO(#144016): once more distance functions are supported, store the
261+
// operator on the index and use it here.
262+
if col.GetID() == index.VectorColumnID() {
263+
f.WriteString(" vector_l2_ops")
258264
}
259265
}
260266
// The last column of an inverted or vector index cannot have a DESC

pkg/sql/catalog/catformat/index_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,16 +277,16 @@ func TestIndexForDisplay(t *testing.T) {
277277
tableName: descpb.AnonymousTable,
278278
partition: "",
279279
displayMode: IndexDisplayDefOnly,
280-
expected: "VECTOR INDEX baz (a)",
281-
pgExpected: "INDEX baz USING cspann (a)",
280+
expected: "VECTOR INDEX baz (a vector_l2_ops)",
281+
pgExpected: "INDEX baz USING cspann (a vector_l2_ops)",
282282
},
283283
{
284284
index: vectorIndex,
285285
tableName: tableName,
286286
partition: "",
287287
displayMode: IndexDisplayShowCreate,
288-
expected: "CREATE VECTOR INDEX baz ON foo.public.bar (a)",
289-
pgExpected: "CREATE INDEX baz ON foo.public.bar USING cspann (a)",
288+
expected: "CREATE VECTOR INDEX baz ON foo.public.bar (a vector_l2_ops)",
289+
pgExpected: "CREATE INDEX baz ON foo.public.bar USING cspann (a vector_l2_ops)",
290290
},
291291
}
292292

pkg/sql/create_index.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,17 @@ func makeIndexDescriptor(
256256
}
257257

258258
vecCol := columns[len(columns)-1]
259+
switch vecCol.OpClass {
260+
case "vector_l2_ops", "":
261+
// vector_l2_ops is the default operator class. This allows users to omit
262+
// the operator class in index definitions.
263+
case "vector_l1_ops", "vector_ip_ops", "vector_cosine_ops",
264+
"bit_hamming_ops", "bit_jaccard_ops":
265+
return nil, unimplemented.NewWithIssuef(144016,
266+
"operator class %v is not supported", vecCol.OpClass)
267+
default:
268+
return nil, newUndefinedOpclassError(vecCol.OpClass)
269+
}
259270
column, err := catalog.MustFindColumnByTreeName(tableDesc, vecCol.Column)
260271
if err != nil {
261272
return nil, err
@@ -372,7 +383,7 @@ func checkIndexColumns(
372383
}
373384
if colDef.OpClass != "" && (i < len(columns)-1 || !indexType.SupportsOpClass()) {
374385
return pgerror.New(pgcode.DatatypeMismatch,
375-
"operator classes are only allowed for the last column of an inverted index")
386+
"operator classes are only allowed for the last column of an inverted or vector index")
376387
}
377388
}
378389
for i, colName := range storing {

pkg/sql/logictest/testdata/logic_test/create_index

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,12 @@ CREATE TABLE opclasses (a INT PRIMARY KEY, b TEXT, c JSON)
422422

423423
# Make sure that we don't permit creating indexes with opclasses that aren't
424424
# inverted.
425-
statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
425+
statement error pgcode 42804 operator classes are only allowed for the last column of an inverted or vector index
426426
CREATE INDEX ON opclasses(b blah_ops)
427427

428428
# Make sure that we don't permit creating indexes with opclasses that aren't
429429
# inverted, even if the type is invertible.
430-
statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
430+
statement error pgcode 42804 operator classes are only allowed for the last column of an inverted or vector index
431431
CREATE INDEX ON opclasses(c blah_ops)
432432

433433
# Make sure that we don't permit creating indexes with opclasses that don't exist

pkg/sql/logictest/testdata/logic_test/create_table

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ like_indexes CREATE TABLE public.like_indexes (
219219
UNIQUE INDEX foo (b DESC, c ASC),
220220
INDEX like_table_c_idx (c ASC) STORING (j),
221221
INVERTED INDEX like_table_j_idx (j),
222-
VECTOR INDEX like_table_v_idx (v)
222+
VECTOR INDEX like_table_v_idx (v vector_l2_ops)
223223
)
224224

225225
# INCLUDING GENERATED adds "generated columns", aka stored columns.
@@ -280,7 +280,7 @@ like_all CREATE TABLE public.like_all (
280280
UNIQUE INDEX foo (b DESC, c ASC),
281281
INDEX like_table_c_idx (c ASC) STORING (j),
282282
INVERTED INDEX like_table_j_idx (j),
283-
VECTOR INDEX like_table_v_idx (v),
283+
VECTOR INDEX like_table_v_idx (v vector_l2_ops),
284284
CONSTRAINT check_a CHECK (a > 3:::INT8),
285285
CONSTRAINT unique_k UNIQUE WITHOUT INDEX (k),
286286
CONSTRAINT unique_h UNIQUE WITHOUT INDEX (h),
@@ -308,7 +308,7 @@ like_mixed CREATE TABLE public.like_mixed (
308308
UNIQUE INDEX foo (b DESC, c ASC),
309309
INDEX like_table_c_idx (c ASC) STORING (j),
310310
INVERTED INDEX like_table_j_idx (j),
311-
VECTOR INDEX like_table_v_idx (v)
311+
VECTOR INDEX like_table_v_idx (v vector_l2_ops)
312312
)
313313

314314
statement ok

0 commit comments

Comments
 (0)