Compare commits

..

1 Commits

Author SHA1 Message Date
Andrew Kane
1bc29ac697 Added tuple stats for HNSW [skip ci] 2024-07-13 08:47:53 -07:00
57 changed files with 221 additions and 272 deletions

View File

@@ -1,11 +1,5 @@
## 0.7.4 (2024-08-05) ## 0.7.3 (unreleased)
- Fixed locking for parallel HNSW index builds
- Fixed compilation error with GCC 14 on i386 when SSE2 is not enabled
## 0.7.3 (2024-07-22)
- Fixed `failed to add index item` error with `sparsevec`
- Fixed compilation error with FreeBSD ARM - Fixed compilation error with FreeBSD ARM
- Fixed compilation warning with MSVC and Postgres 16 - Fixed compilation warning with MSVC and Postgres 16

View File

@@ -2,7 +2,7 @@
"name": "vector", "name": "vector",
"abstract": "Open-source vector similarity search for Postgres", "abstract": "Open-source vector similarity search for Postgres",
"description": "Supports L2 distance, inner product, and cosine distance", "description": "Supports L2 distance, inner product, and cosine distance",
"version": "0.7.4", "version": "0.7.2",
"maintainer": [ "maintainer": [
"Andrew Kane <andrew@ankane.org>" "Andrew Kane <andrew@ankane.org>"
], ],
@@ -20,7 +20,7 @@
"vector": { "vector": {
"file": "sql/vector.sql", "file": "sql/vector.sql",
"docfile": "README.md", "docfile": "README.md",
"version": "0.7.4", "version": "0.7.2",
"abstract": "Open-source vector similarity search for Postgres" "abstract": "Open-source vector similarity search for Postgres"
} }
}, },

View File

@@ -1,9 +1,8 @@
EXTENSION = vector EXTENSION = vector
EXTVERSION = 0.7.4 EXTVERSION = 0.7.2
MODULE_big = vector MODULE_big = vector
DATA = $(wildcard sql/*--*--*.sql) DATA = $(wildcard sql/*--*.sql)
DATA_built = sql/$(EXTENSION)--$(EXTVERSION).sql
OBJS = src/bitutils.o src/bitvec.o src/halfutils.o src/halfvec.o src/hnsw.o src/hnswbuild.o src/hnswinsert.o src/hnswscan.o src/hnswutils.o src/hnswvacuum.o src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/sparsevec.o src/vector.o OBJS = src/bitutils.o src/bitvec.o src/halfutils.o src/halfvec.o src/hnsw.o src/hnswbuild.o src/hnswinsert.o src/hnswscan.o src/hnswutils.o src/hnswvacuum.o src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/sparsevec.o src/vector.o
HEADERS = src/halfvec.h src/sparsevec.h src/vector.h HEADERS = src/halfvec.h src/sparsevec.h src/vector.h
@@ -43,6 +42,8 @@ all: sql/$(EXTENSION)--$(EXTVERSION).sql
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
cp $< $@ cp $< $@
EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql
PG_CONFIG ?= pg_config PG_CONFIG ?= pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs) PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS) include $(PGXS)
@@ -52,7 +53,7 @@ ifeq ($(PROVE),)
PROVE = prove PROVE = prove
endif endif
# for Postgres < 15 # for Postgres 15
PROVE_FLAGS += -I ./test/perl PROVE_FLAGS += -I ./test/perl
prove_installcheck: prove_installcheck:

View File

@@ -1,7 +1,6 @@
EXTENSION = vector EXTENSION = vector
EXTVERSION = 0.7.4 EXTVERSION = 0.7.2
DATA_built = sql\$(EXTENSION)--$(EXTVERSION).sql
OBJS = src\bitutils.obj src\bitvec.obj src\halfutils.obj src\halfvec.obj src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\sparsevec.obj src\vector.obj OBJS = src\bitutils.obj src\bitvec.obj src\halfutils.obj src\halfvec.obj src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\sparsevec.obj src\vector.obj
HEADERS = src\halfvec.h src\sparsevec.h src\vector.h HEADERS = src\halfvec.h src\sparsevec.h src\vector.h
@@ -20,6 +19,11 @@ PG_CFLAGS = $(PG_CFLAGS) $(OPTFLAGS) /O2 /fp:fast
# https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/vectorizer-and-parallelizer-messages # https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/vectorizer-and-parallelizer-messages
# PG_CFLAGS = $(PG_CFLAGS) /Qvec-report:2 # PG_CFLAGS = $(PG_CFLAGS) /Qvec-report:2
all: sql\$(EXTENSION)--$(EXTVERSION).sql
sql\$(EXTENSION)--$(EXTVERSION).sql: sql\$(EXTENSION).sql
copy sql\$(EXTENSION).sql $@
# TODO use pg_config # TODO use pg_config
!ifndef PGROOT !ifndef PGROOT
!error PGROOT is not set !error PGROOT is not set
@@ -39,18 +43,15 @@ SHLIB = $(EXTENSION).dll
LIBS = "$(LIBDIR)\postgres.lib" LIBS = "$(LIBDIR)\postgres.lib"
all: $(SHLIB) $(DATA_built)
.c.obj: .c.obj:
$(CC) $(CFLAGS) /c $< /Fo$@ $(CC) $(CFLAGS) /c $< /Fo$@
$(SHLIB): $(OBJS) $(SHLIB): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(LIBS) /link /DLL /OUT:$(SHLIB) $(CC) $(CFLAGS) $(OBJS) $(LIBS) /link /DLL /OUT:$(SHLIB)
sql\$(EXTENSION)--$(EXTVERSION).sql: sql\$(EXTENSION).sql all: $(SHLIB)
copy sql\$(EXTENSION).sql $@
install: all install:
copy $(SHLIB) "$(PKGLIBDIR)" copy $(SHLIB) "$(PKGLIBDIR)"
copy $(EXTENSION).control "$(SHAREDIR)\extension" copy $(EXTENSION).control "$(SHAREDIR)\extension"
copy sql\$(EXTENSION)--*.sql "$(SHAREDIR)\extension" copy sql\$(EXTENSION)--*.sql "$(SHAREDIR)\extension"
@@ -69,6 +70,6 @@ uninstall:
clean: clean:
del /f $(SHLIB) $(EXTENSION).lib $(EXTENSION).exp del /f $(SHLIB) $(EXTENSION).lib $(EXTENSION).exp
del /f $(DATA_built)
del /f $(OBJS) del /f $(OBJS)
del /f sql\$(EXTENSION)--$(EXTVERSION).sql
del /f /s /q results regression.diffs regression.out tmp_check tmp_check_iso log output_iso del /f /s /q results regression.diffs regression.out tmp_check tmp_check_iso log output_iso

View File

@@ -21,7 +21,7 @@ Compile and install the extension (supports Postgres 12+)
```sh ```sh
cd /tmp cd /tmp
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
make make
make install # may need sudo make install # may need sudo
@@ -46,7 +46,7 @@ Then use `nmake` to build:
```cmd ```cmd
set "PGROOT=C:\Program Files\PostgreSQL\16" set "PGROOT=C:\Program Files\PostgreSQL\16"
cd %TEMP% cd %TEMP%
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
nmake /F Makefile.win nmake /F Makefile.win
nmake /F Makefile.win install nmake /F Makefile.win install
@@ -1051,7 +1051,7 @@ This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres) (r
You can also build the image manually: You can also build the image manually:
```sh ```sh
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
docker build --pull --build-arg PG_MAJOR=16 -t myuser/pgvector . docker build --pull --build-arg PG_MAJOR=16 -t myuser/pgvector .
``` ```

View File

@@ -1,2 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION vector UPDATE TO '0.7.3'" to load this file. \quit

View File

@@ -1,2 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION vector UPDATE TO '0.7.4'" to load this file. \quit

View File

@@ -38,7 +38,7 @@
/* F16C has better performance than _Float16 (on x86-64) */ /* F16C has better performance than _Float16 (on x86-64) */
#if defined(__F16C__) #if defined(__F16C__)
#define F16C_SUPPORT #define F16C_SUPPORT
#elif defined(__FLT16_MAX__) && !defined(HALFVEC_DISPATCH) && !defined(__FreeBSD__) && (!defined(__i386__) || defined(__SSE2__)) #elif defined(__FLT16_MAX__) && !defined(HALFVEC_DISPATCH) && !defined(__FreeBSD__)
#define FLT16_SUPPORT #define FLT16_SUPPORT
#endif #endif

View File

@@ -20,6 +20,10 @@ int hnsw_ef_search;
int hnsw_lock_tranche_id; int hnsw_lock_tranche_id;
static relopt_kind hnsw_relopt_kind; static relopt_kind hnsw_relopt_kind;
#ifdef HNSW_STATS
int hnsw_tuples;
#endif
/* /*
* Assign a tranche ID for our LWLocks. This only needs to be done by one * Assign a tranche ID for our LWLocks. This only needs to be done by one
* backend, as the tranche ID is remembered in shared memory. * backend, as the tranche ID is remembered in shared memory.
@@ -135,6 +139,10 @@ hnswcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
genericcostestimate(root, path, loop_count, &costs); genericcostestimate(root, path, loop_count, &costs);
#ifdef HNSW_STATS
elog(INFO, "estimated tuples = %0.f", costs.numIndexTuples);
#endif
/* Use total cost since most work happens before first tuple is returned */ /* Use total cost since most work happens before first tuple is returned */
*indexStartupCost = costs.indexTotalCost; *indexStartupCost = costs.indexTotalCost;
*indexTotalCost = costs.indexTotalCost; *indexTotalCost = costs.indexTotalCost;

View File

@@ -113,6 +113,10 @@
extern int hnsw_ef_search; extern int hnsw_ef_search;
extern int hnsw_lock_tranche_id; extern int hnsw_lock_tranche_id;
#ifdef HNSW_STATS
extern int hnsw_tuples;
#endif
typedef struct HnswElementData HnswElementData; typedef struct HnswElementData HnswElementData;
typedef struct HnswNeighborArray HnswNeighborArray; typedef struct HnswNeighborArray HnswNeighborArray;

View File

@@ -379,13 +379,7 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
for (int lc = e->level; lc >= 0; lc--) for (int lc = e->level; lc >= 0; lc--)
{ {
int lm = HnswGetLayerM(m, lc); int lm = HnswGetLayerM(m, lc);
Size neighborsSize = HNSW_NEIGHBOR_ARRAY_SIZE(lm); HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc);
HnswNeighborArray *neighbors = palloc(neighborsSize);
/* Copy neighbors to local memory */
LWLockAcquire(&e->lock, LW_SHARED);
memcpy(neighbors, HnswGetNeighbors(base, e, lc), neighborsSize);
LWLockRelease(&e->lock);
for (int i = 0; i < neighbors->length; i++) for (int i = 0; i < neighbors->length; i++)
{ {
@@ -395,6 +389,7 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
/* Keep scan-build happy on Mac x86-64 */ /* Keep scan-build happy on Mac x86-64 */
Assert(neighborElement); Assert(neighborElement);
/* Use element for lock instead of hc since hc can be replaced */
LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE); LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE);
HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation); HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation);
LWLockRelease(&neighborElement->lock); LWLockRelease(&neighborElement->lock);

View File

@@ -36,15 +36,14 @@ GetInsertPage(Relation index)
* Check for a free offset * Check for a free offset
*/ */
static bool static bool
HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size etupSize, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage) HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage)
{ {
OffsetNumber offno; OffsetNumber offno;
OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); OffsetNumber maxoffno = PageGetMaxOffsetNumber(page);
for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno))
{ {
ItemId eitemid = PageGetItemId(page, offno); HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno));
HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, eitemid);
/* Skip neighbor tuples */ /* Skip neighbor tuples */
if (!HnswIsElementTuple(etup)) if (!HnswIsElementTuple(etup))
@@ -55,9 +54,7 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size
BlockNumber elementPage = BufferGetBlockNumber(buf); BlockNumber elementPage = BufferGetBlockNumber(buf);
BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid);
OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid);
ItemId nitemid; ItemId itemid;
Size pageFree;
Size npageFree;
if (!BlockNumberIsValid(*newInsertPage)) if (!BlockNumberIsValid(*newInsertPage))
*newInsertPage = elementPage; *newInsertPage = elementPage;
@@ -76,25 +73,10 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size
*npage = BufferGetPage(*nbuf); *npage = BufferGetPage(*nbuf);
} }
nitemid = PageGetItemId(*npage, neighborOffno); itemid = PageGetItemId(*npage, neighborOffno);
/* Ensure aligned for space check */ /* Check for space on neighbor tuple page */
Assert(etupSize == MAXALIGN(etupSize)); if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize)
Assert(ntupSize == MAXALIGN(ntupSize));
/*
* Calculate free space individually since tuples are overwritten
* individually (in separate calls to PageIndexTupleOverwrite)
*/
pageFree = ItemIdGetLength(eitemid) + PageGetExactFreeSpace(page);
npageFree = ItemIdGetLength(nitemid);
if (neighborPage != elementPage)
npageFree += PageGetExactFreeSpace(*npage);
else if (pageFree >= etupSize)
npageFree += pageFree - etupSize;
/* Check for space */
if (pageFree >= etupSize && npageFree >= ntupSize)
{ {
*freeOffno = offno; *freeOffno = offno;
*freeNeighborOffno = neighborOffno; *freeNeighborOffno = neighborOffno;
@@ -202,7 +184,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B
} }
/* Next, try space from a deleted element */ /* Next, try space from a deleted element */
if (HnswFreeOffset(index, buf, page, e, etupSize, ntupSize, &nbuf, &npage, &freeOffno, &freeNeighborOffno, &newInsertPage)) if (HnswFreeOffset(index, buf, page, e, ntupSize, &nbuf, &npage, &freeOffno, &freeNeighborOffno, &newInsertPage))
{ {
if (nbuf != buf) if (nbuf != buf)
{ {

View File

@@ -31,13 +31,23 @@ GetScanItems(IndexScanDesc scan, Datum q)
ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, false)); ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, false));
#ifdef HNSW_STATS
hnsw_tuples = 1;
#endif
for (int lc = entryPoint->level; lc >= 1; lc--) for (int lc = entryPoint->level; lc >= 1; lc--)
{ {
w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, false, NULL); w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, false, NULL);
ep = w; ep = w;
} }
return HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, procinfo, collation, m, false, NULL); w = HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, procinfo, collation, m, false, NULL);
#ifdef HNSW_STATS
elog(INFO, "total tuples = %d", hnsw_tuples);
#endif
return w;
} }
/* /*

View File

@@ -801,6 +801,11 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F
HnswElement eElement = HnswPtrAccess(base, e->element); HnswElement eElement = HnswPtrAccess(base, e->element);
bool alwaysAdd = wlen < ef; bool alwaysAdd = wlen < ef;
#ifdef HNSW_STATS
if (!inserting)
hnsw_tuples++;
#endif
f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner;
if (index == NULL) if (index == NULL)

View File

@@ -1,11 +0,0 @@
package PostgreSQL::Test::Cluster;
use PostgresNode;
sub new
{
my ($class, $name) = @_;
return get_new_node($name);
}
1;

View File

@@ -1,5 +0,0 @@
package PostgreSQL::Test::Utils;
use TestLib;
1;

View File

@@ -0,0 +1,8 @@
use PostgreSQL::Test::Cluster;
sub get_new_node
{
return PostgreSQL::Test::Cluster->new(@_);
}
1;

3
test/perl/TestLib.pm Normal file
View File

@@ -0,0 +1,3 @@
use PostgreSQL::Test::Utils;
1;

View File

@@ -2,9 +2,9 @@
# Test generic xlog record work for ivfflat index replication. # Test generic xlog record work for ivfflat index replication.
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 32; my $dim = 32;
@@ -49,7 +49,7 @@ sub test_index_replay
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize primary node # Initialize primary node
$node_primary = PostgreSQL::Test::Cluster->new('primary'); $node_primary = get_new_node('primary');
$node_primary->init(allows_streaming => 1); $node_primary->init(allows_streaming => 1);
if ($dim > 32) if ($dim > 32)
{ {
@@ -67,7 +67,7 @@ my $backup_name = 'my_backup';
$node_primary->backup($backup_name); $node_primary->backup($backup_name);
# Create streaming replica linking to primary # Create streaming replica linking to primary
$node_replica = PostgreSQL::Test::Cluster->new('replica'); $node_replica = get_new_node('replica');
$node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1); $node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1);
$node_replica->start; $node_replica->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 3; my $dim = 3;
@@ -15,7 +15,7 @@ for (1 .. $dim)
my $array_sql = join(", ", @r); my $array_sql = join(", ", @r);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -49,7 +49,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 768; my $dim = 768;
@@ -9,7 +9,7 @@ my $dim = 768;
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 3; my $dim = 3;
@@ -11,7 +11,7 @@ my $limit = 20;
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -2,9 +2,9 @@
# Test generic xlog record work for hnsw index replication. # Test generic xlog record work for hnsw index replication.
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 32; my $dim = 32;
@@ -49,7 +49,7 @@ sub test_index_replay
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize primary node # Initialize primary node
$node_primary = PostgreSQL::Test::Cluster->new('primary'); $node_primary = get_new_node('primary');
$node_primary->init(allows_streaming => 1); $node_primary->init(allows_streaming => 1);
if ($dim > 32) if ($dim > 32)
{ {
@@ -67,7 +67,7 @@ my $backup_name = 'my_backup';
$node_primary->backup($backup_name); $node_primary->backup($backup_name);
# Create streaming replica linking to primary # Create streaming replica linking to primary
$node_replica = PostgreSQL::Test::Cluster->new('replica'); $node_replica = get_new_node('replica');
$node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1); $node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1);
$node_replica->start; $node_replica->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 3; my $dim = 3;
@@ -15,7 +15,7 @@ for (1 .. $dim)
my $array_sql = join(", ", @r); my $array_sql = join(", ", @r);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -47,7 +47,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -47,7 +47,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Ensures elements and neighbors on both same and different pages # Ensures elements and neighbors on both same and different pages
@@ -10,7 +10,7 @@ my $dim = 1900;
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 3; my $dim = 3;
@@ -11,7 +11,7 @@ my $limit = 20;
my $array_sql = join(",", ('random()') x $dim); my $array_sql = join(",", ('random()') x $dim);
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;
@@ -53,7 +53,7 @@ sub test_aggregate
else else
{ {
# Does not raise overflow error in this instance due to loss of precision # Does not raise overflow error in this instance due to loss of precision
is($res, "[24576,24576,49152]"); is($res, "[24576,24576,49152]")
} }
} }

View File

@@ -1,13 +1,13 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $dim = 1024; my $dim = 1024;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -51,7 +51,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -51,7 +51,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -51,7 +51,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -47,7 +47,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -47,7 +47,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -48,7 +48,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -51,7 +51,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,14 +1,14 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
my $array_sql = join(",", ('floor(random() * 2)::int - 1') x 3); my $array_sql = join(",", ('floor(random() * 2)::int - 1') x 3);
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -10,7 +10,7 @@ my $dim = 5;
my $array_sql = join(",", ('floor(random() * 4)::int - 2') x $dim); my $array_sql = join(",", ('floor(random() * 4)::int - 2') x $dim);
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,7 +1,7 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
my $node; my $node;
@@ -51,7 +51,7 @@ sub test_recall
} }
# Initialize node # Initialize node
$node = PostgreSQL::Test::Cluster->new('node'); $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,11 +1,11 @@
use strict; use strict;
use warnings FATAL => 'all'; use warnings;
use PostgreSQL::Test::Cluster; use PostgresNode;
use PostgreSQL::Test::Utils; use TestLib;
use Test::More; use Test::More;
# Initialize node # Initialize node
my $node = PostgreSQL::Test::Cluster->new('node'); my $node = get_new_node('node');
$node->init; $node->init;
$node->start; $node->start;

View File

@@ -1,42 +0,0 @@
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
# Initialize node
my $node = PostgreSQL::Test::Cluster->new('node');
$node->init;
$node->start;
# Create table and index
$node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (i serial, v sparsevec(100000));");
$node->safe_psql("postgres", "CREATE INDEX ON tst USING hnsw (v sparsevec_l2_ops);");
for (1 .. 3)
{
for (1 .. 100)
{
my @elements;
my %indices;
for (1 .. int(rand() * 100))
{
my $index = int(rand() * (100000 - 1)) + 1;
if (!exists($indices{$index}))
{
my $value = rand();
push(@elements, "$index:$value");
$indices{$index} = 1;
}
}
my $embedding = "{" . join(",", @elements) . "}/100000";
$node->safe_psql("postgres", "INSERT INTO tst (v) VALUES ('$embedding');");
}
$node->safe_psql("postgres", "DELETE FROM tst WHERE i % 2 = 0;");
$node->safe_psql("postgres", "VACUUM tst;");
is(1, 1);
}
done_testing();

View File

@@ -1,4 +1,4 @@
comment = 'vector data type and ivfflat and hnsw access methods' comment = 'vector data type and ivfflat and hnsw access methods'
default_version = '0.7.4' default_version = '0.7.2'
module_pathname = '$libdir/vector' module_pathname = '$libdir/vector'
relocatable = true relocatable = true