Tried switching column order [skip ci]

This commit is contained in:
Andrew Kane
2024-02-13 13:07:30 -08:00
parent f712847781
commit c66a6de0bd
8 changed files with 39 additions and 31 deletions

View File

@@ -4,3 +4,7 @@
CREATE OPERATOR CLASS vector_integer_ops CREATE OPERATOR CLASS vector_integer_ops
DEFAULT FOR TYPE integer USING hnsw AS DEFAULT FOR TYPE integer USING hnsw AS
OPERATOR 2 = (integer, integer); OPERATOR 2 = (integer, integer);
CREATE OPERATOR CLASS vector_bigint_ops
DEFAULT FOR TYPE bigint USING hnsw AS
OPERATOR 2 = (bigint, bigint);

View File

@@ -296,3 +296,7 @@ CREATE OPERATOR CLASS vector_cosine_ops
CREATE OPERATOR CLASS vector_integer_ops CREATE OPERATOR CLASS vector_integer_ops
DEFAULT FOR TYPE integer USING hnsw AS DEFAULT FOR TYPE integer USING hnsw AS
OPERATOR 2 = (integer, integer); OPERATOR 2 = (integer, integer);
CREATE OPERATOR CLASS vector_bigint_ops
DEFAULT FOR TYPE bigint USING hnsw AS
OPERATOR 2 = (bigint, bigint);

View File

@@ -481,7 +481,7 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
bool unused; bool unused;
/* Detoast once for all calls */ /* Detoast once for all calls */
Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[IndexRelationGetNumberOfKeyAttributes(index) - 1]));
/* Normalize if needed */ /* Normalize if needed */
if (buildstate->normprocinfo != NULL) if (buildstate->normprocinfo != NULL)
@@ -551,7 +551,7 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
/* Copy the index tuple */ /* Copy the index tuple */
memcpy(itupPtr, itup, itupSize); memcpy(itupPtr, itup, itupSize);
HnswPtrStore(base, element->itup, itupPtr); HnswPtrStore(base, element->itup, itupPtr);
valuePtr = DatumGetPointer(index_getattr(itupPtr, 1, tupdesc, &unused)); valuePtr = DatumGetPointer(index_getattr(itupPtr, IndexRelationGetNumberOfKeyAttributes(index), tupdesc, &unused));
HnswPtrStore(base, element->value, valuePtr); HnswPtrStore(base, element->value, valuePtr);
/* Create a lock for the element */ /* Create a lock for the element */
@@ -582,7 +582,7 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values,
#endif #endif
/* Skip nulls */ /* Skip nulls */
if (isnull[0]) if (isnull[IndexRelationGetNumberOfKeyAttributes(index) - 1])
return; return;
/* Use memory context */ /* Use memory context */
@@ -674,16 +674,16 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
buildstate->m = HnswGetM(index); buildstate->m = HnswGetM(index);
buildstate->efConstruction = HnswGetEfConstruction(index); buildstate->efConstruction = HnswGetEfConstruction(index);
buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod; buildstate->dimensions = TupleDescAttr(index->rd_att, IndexRelationGetNumberOfKeyAttributes(index) - 1)->atttypmod;
/* For now */ /* For now */
if (IndexRelationGetNumberOfKeyAttributes(index) > 2) if (IndexRelationGetNumberOfKeyAttributes(index) > 2)
elog(ERROR, "index cannot have more than two columns"); elog(ERROR, "index cannot have more than two columns");
if (!OidIsValid(index_getprocid(index, 1, HNSW_DISTANCE_PROC))) if (!OidIsValid(index_getprocid(index, IndexRelationGetNumberOfKeyAttributes(index), HNSW_DISTANCE_PROC)))
elog(ERROR, "first column must be a vector"); elog(ERROR, "last column must be a vector");
for (int i = 1; i < IndexRelationGetNumberOfKeyAttributes(index); i++) for (int i = 0; i < IndexRelationGetNumberOfKeyAttributes(index) - 1; i++)
{ {
if (OidIsValid(index_getprocid(index, i + 1, HNSW_DISTANCE_PROC))) if (OidIsValid(index_getprocid(index, i + 1, HNSW_DISTANCE_PROC)))
elog(ERROR, "column %d cannot be a vector", i + 1); elog(ERROR, "column %d cannot be a vector", i + 1);
@@ -703,9 +703,9 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
buildstate->indtuples = 0; buildstate->indtuples = 0;
/* Get support functions */ /* Get support functions */
buildstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); buildstate->procinfo = index_getprocinfo(index, IndexRelationGetNumberOfKeyAttributes(index), HNSW_DISTANCE_PROC);
buildstate->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); buildstate->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC);
buildstate->collation = index->rd_indcollation[0]; buildstate->collation = index->rd_indcollation[IndexRelationGetNumberOfKeyAttributes(index) - 1];
InitGraph(&buildstate->graphData, NULL, maintenance_work_mem * 1024L); InitGraph(&buildstate->graphData, NULL, maintenance_work_mem * 1024L);
buildstate->graph = &buildstate->graphData; buildstate->graph = &buildstate->graphData;

View File

@@ -561,8 +561,8 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, bool *isnull,
HnswElement element; HnswElement element;
int m; int m;
int efConstruction = HnswGetEfConstruction(index); int efConstruction = HnswGetEfConstruction(index);
FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); FmgrInfo *procinfo = index_getprocinfo(index, IndexRelationGetNumberOfKeyAttributes(index), HNSW_DISTANCE_PROC);
Oid collation = index->rd_indcollation[0]; Oid collation = index->rd_indcollation[IndexRelationGetNumberOfKeyAttributes(index) - 1];
LOCKMODE lockmode = ShareLock; LOCKMODE lockmode = ShareLock;
char *base = NULL; char *base = NULL;
TupleDesc tupdesc = HnswTupleDesc(index); TupleDesc tupdesc = HnswTupleDesc(index);
@@ -584,7 +584,7 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, bool *isnull,
element = HnswInitElement(base, heap_tid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL); element = HnswInitElement(base, heap_tid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL);
itup = HnswFormIndexTuple(index, tupdesc, value, values, isnull); itup = HnswFormIndexTuple(index, tupdesc, value, values, isnull);
HnswPtrStore(base, element->itup, itup); HnswPtrStore(base, element->itup, itup);
valuePtr = DatumGetPointer(index_getattr(itup, 1, tupdesc, &unused)); valuePtr = DatumGetPointer(index_getattr(itup, IndexRelationGetNumberOfKeyAttributes(index), tupdesc, &unused));
HnswPtrStore(base, element->value, valuePtr); HnswPtrStore(base, element->value, valuePtr);
/* Prevent concurrent inserts when likely updating entry point */ /* Prevent concurrent inserts when likely updating entry point */
@@ -621,10 +621,10 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
{ {
Datum value; Datum value;
FmgrInfo *normprocinfo; FmgrInfo *normprocinfo;
Oid collation = index->rd_indcollation[0]; Oid collation = index->rd_indcollation[IndexRelationGetNumberOfKeyAttributes(index) - 1];
/* Detoast once for all calls */ /* Detoast once for all calls */
value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); value = PointerGetDatum(PG_DETOAST_DATUM(values[IndexRelationGetNumberOfKeyAttributes(index) - 1]));
/* Normalize if needed */ /* Normalize if needed */
normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC);
@@ -653,7 +653,7 @@ hnswinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid,
MemoryContext insertCtx; MemoryContext insertCtx;
/* Skip nulls */ /* Skip nulls */
if (isnull[0]) if (isnull[IndexRelationGetNumberOfKeyAttributes(index) - 1])
return false; return false;
/* Create memory context */ /* Create memory context */

View File

@@ -109,9 +109,9 @@ hnswbeginscan(Relation index, int nkeys, int norderbys)
ALLOCSET_DEFAULT_SIZES); ALLOCSET_DEFAULT_SIZES);
/* Set support functions */ /* Set support functions */
so->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); so->procinfo = index_getprocinfo(index, IndexRelationGetNumberOfKeyAttributes(index), HNSW_DISTANCE_PROC);
so->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); so->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC);
so->collation = index->rd_indcollation[0]; so->collation = index->rd_indcollation[IndexRelationGetNumberOfKeyAttributes(index) - 1];
scan->opaque = so; scan->opaque = so;

View File

@@ -148,10 +148,10 @@ HnswGetEfConstruction(Relation index)
FmgrInfo * FmgrInfo *
HnswOptionalProcInfo(Relation index, uint16 procnum) HnswOptionalProcInfo(Relation index, uint16 procnum)
{ {
if (!OidIsValid(index_getprocid(index, 1, procnum))) if (!OidIsValid(index_getprocid(index, IndexRelationGetNumberOfKeyAttributes(index), procnum)))
return NULL; return NULL;
return index_getprocinfo(index, 1, procnum); return index_getprocinfo(index, IndexRelationGetNumberOfKeyAttributes(index), procnum);
} }
/* /*
@@ -324,7 +324,7 @@ HnswFormIndexTuple(Relation index, TupleDesc tupdesc, Datum value, Datum *values
Datum *newValues = palloc(size); Datum *newValues = palloc(size);
memcpy(newValues, values, size); memcpy(newValues, values, size);
newValues[0] = value; newValues[IndexRelationGetNumberOfKeyAttributes(index) - 1] = value;
return index_form_tuple(tupdesc, newValues, isnull); return index_form_tuple(tupdesc, newValues, isnull);
} }
@@ -642,7 +642,7 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe
TupleDesc tupdesc = RelationGetDescr(index); TupleDesc tupdesc = RelationGetDescr(index);
bool unused; bool unused;
IndexTuple itup = CopyIndexTuple((IndexTuple) &etup->data); IndexTuple itup = CopyIndexTuple((IndexTuple) &etup->data);
Datum value = index_getattr(itup, 1, tupdesc, &unused); Datum value = index_getattr(itup, IndexRelationGetNumberOfKeyAttributes(index), tupdesc, &unused);
HnswPtrStore(base, element->itup, itup); HnswPtrStore(base, element->itup, itup);
HnswPtrStore(base, element->value, DatumGetPointer(value)); HnswPtrStore(base, element->value, DatumGetPointer(value));
@@ -722,7 +722,7 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index,
TupleDesc tupdesc = RelationGetDescr(index); TupleDesc tupdesc = RelationGetDescr(index);
bool unused; bool unused;
value = index_getattr(itup, 1, tupdesc, &unused); value = index_getattr(itup, IndexRelationGetNumberOfKeyAttributes(index), tupdesc, &unused);
} }
else else
value = PointerGetDatum(&etup->data); value = PointerGetDatum(&etup->data);

View File

@@ -585,8 +585,8 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD
vacuumstate->callback_state = callback_state; vacuumstate->callback_state = callback_state;
vacuumstate->efConstruction = HnswGetEfConstruction(index); vacuumstate->efConstruction = HnswGetEfConstruction(index);
vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD); vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD);
vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); vacuumstate->procinfo = index_getprocinfo(index, IndexRelationGetNumberOfKeyAttributes(index), HNSW_DISTANCE_PROC);
vacuumstate->collation = index->rd_indcollation[0]; vacuumstate->collation = index->rd_indcollation[IndexRelationGetNumberOfKeyAttributes(index) - 1];
vacuumstate->ntup = palloc0(HNSW_TUPLE_ALLOC_SIZE); vacuumstate->ntup = palloc0(HNSW_TUPLE_ALLOC_SIZE);
vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
"Hnsw vacuum temporary context", "Hnsw vacuum temporary context",

View File

@@ -58,11 +58,11 @@ $node->start;
# Create table # Create table
$node->safe_psql("postgres", "CREATE EXTENSION vector;"); $node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (i int4, v vector($dim), c int4);"); $node->safe_psql("postgres", "CREATE TABLE tst (i int4, v vector($dim), c int8);");
$node->safe_psql("postgres", $node->safe_psql("postgres",
"INSERT INTO tst SELECT i, ARRAY[$array_sql], i % $nc FROM generate_series(1, 10000) i;" "INSERT INTO tst SELECT i, ARRAY[$array_sql], i % $nc FROM generate_series(1, 10000) i;"
); );
$node->safe_psql("postgres", "CREATE INDEX ON tst USING hnsw (v vector_l2_ops, c);"); $node->safe_psql("postgres", "CREATE INDEX ON tst USING hnsw (c, v vector_l2_ops);");
$node->safe_psql("postgres", $node->safe_psql("postgres",
"INSERT INTO tst SELECT i, ARRAY[$array_sql], i % $nc FROM generate_series(1, 10000) i;" "INSERT INTO tst SELECT i, ARRAY[$array_sql], i % $nc FROM generate_series(1, 10000) i;"
); );
@@ -99,15 +99,15 @@ $node->safe_psql("postgres", "VACUUM tst;");
# Test columns # Test columns
my ($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (c);"); my ($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (c);");
like($stderr, qr/first column must be a vector/); like($stderr, qr/last column must be a vector/);
($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (c, v vector_l2_ops);"); ($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (c, c);");
like($stderr, qr/first column must be a vector/); like($stderr, qr/last column must be a vector/);
($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (v vector_l2_ops, c, c);"); ($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (c, c, v vector_l2_ops);");
like($stderr, qr/index cannot have more than two columns/); like($stderr, qr/index cannot have more than two columns/);
($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (v vector_l2_ops, v vector_l2_ops);"); ($ret, $stdout, $stderr) = $node->psql("postgres", "CREATE INDEX ON tst USING hnsw (v vector_l2_ops, v vector_l2_ops);");
like($stderr, qr/column 2 cannot be a vector/); like($stderr, qr/column 1 cannot be a vector/);
done_testing(); done_testing();