mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 20:15:46 +08:00
Compare commits
15 Commits
hnsw-stats
...
v0.7.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
103ac50f1a | ||
|
|
57fb706242 | ||
|
|
020d3edaa9 | ||
|
|
1e9e355175 | ||
|
|
f1d283f565 | ||
|
|
8684c2ba62 | ||
|
|
6c692ef23f | ||
|
|
bb424e96e7 | ||
|
|
30911edb7a | ||
|
|
5ae2bd9efb | ||
|
|
19215317a4 | ||
|
|
c7ca7f05de | ||
|
|
4733cf253b | ||
|
|
06d1fa1402 | ||
|
|
8c5a4bfb6c |
@@ -1,5 +1,11 @@
|
||||
## 0.7.3 (unreleased)
|
||||
## 0.7.4 (2024-08-05)
|
||||
|
||||
- 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 warning with MSVC and Postgres 16
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "vector",
|
||||
"abstract": "Open-source vector similarity search for Postgres",
|
||||
"description": "Supports L2 distance, inner product, and cosine distance",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.4",
|
||||
"maintainer": [
|
||||
"Andrew Kane <andrew@ankane.org>"
|
||||
],
|
||||
@@ -20,7 +20,7 @@
|
||||
"vector": {
|
||||
"file": "sql/vector.sql",
|
||||
"docfile": "README.md",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.4",
|
||||
"abstract": "Open-source vector similarity search for Postgres"
|
||||
}
|
||||
},
|
||||
|
||||
9
Makefile
9
Makefile
@@ -1,8 +1,9 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.7.2
|
||||
EXTVERSION = 0.7.4
|
||||
|
||||
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
|
||||
HEADERS = src/halfvec.h src/sparsevec.h src/vector.h
|
||||
|
||||
@@ -42,8 +43,6 @@ all: sql/$(EXTENSION)--$(EXTVERSION).sql
|
||||
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
|
||||
cp $< $@
|
||||
|
||||
EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql
|
||||
|
||||
PG_CONFIG ?= pg_config
|
||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||
include $(PGXS)
|
||||
@@ -53,7 +52,7 @@ ifeq ($(PROVE),)
|
||||
PROVE = prove
|
||||
endif
|
||||
|
||||
# for Postgres 15
|
||||
# for Postgres < 15
|
||||
PROVE_FLAGS += -I ./test/perl
|
||||
|
||||
prove_installcheck:
|
||||
|
||||
17
Makefile.win
17
Makefile.win
@@ -1,6 +1,7 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.7.2
|
||||
EXTVERSION = 0.7.4
|
||||
|
||||
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
|
||||
HEADERS = src\halfvec.h src\sparsevec.h src\vector.h
|
||||
|
||||
@@ -19,11 +20,6 @@ PG_CFLAGS = $(PG_CFLAGS) $(OPTFLAGS) /O2 /fp:fast
|
||||
# https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/vectorizer-and-parallelizer-messages
|
||||
# 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
|
||||
!ifndef PGROOT
|
||||
!error PGROOT is not set
|
||||
@@ -43,15 +39,18 @@ SHLIB = $(EXTENSION).dll
|
||||
|
||||
LIBS = "$(LIBDIR)\postgres.lib"
|
||||
|
||||
all: $(SHLIB) $(DATA_built)
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) /c $< /Fo$@
|
||||
|
||||
$(SHLIB): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(OBJS) $(LIBS) /link /DLL /OUT:$(SHLIB)
|
||||
|
||||
all: $(SHLIB)
|
||||
sql\$(EXTENSION)--$(EXTVERSION).sql: sql\$(EXTENSION).sql
|
||||
copy sql\$(EXTENSION).sql $@
|
||||
|
||||
install:
|
||||
install: all
|
||||
copy $(SHLIB) "$(PKGLIBDIR)"
|
||||
copy $(EXTENSION).control "$(SHAREDIR)\extension"
|
||||
copy sql\$(EXTENSION)--*.sql "$(SHAREDIR)\extension"
|
||||
@@ -70,6 +69,6 @@ uninstall:
|
||||
|
||||
clean:
|
||||
del /f $(SHLIB) $(EXTENSION).lib $(EXTENSION).exp
|
||||
del /f $(DATA_built)
|
||||
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
|
||||
|
||||
@@ -21,7 +21,7 @@ Compile and install the extension (supports Postgres 12+)
|
||||
|
||||
```sh
|
||||
cd /tmp
|
||||
git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
make install # may need sudo
|
||||
@@ -46,7 +46,7 @@ Then use `nmake` to build:
|
||||
```cmd
|
||||
set "PGROOT=C:\Program Files\PostgreSQL\16"
|
||||
cd %TEMP%
|
||||
git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
nmake /F Makefile.win
|
||||
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:
|
||||
|
||||
```sh
|
||||
git clone --branch v0.7.2 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
docker build --pull --build-arg PG_MAJOR=16 -t myuser/pgvector .
|
||||
```
|
||||
|
||||
2
sql/vector--0.7.2--0.7.3.sql
Normal file
2
sql/vector--0.7.2--0.7.3.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- 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
|
||||
2
sql/vector--0.7.3--0.7.4.sql
Normal file
2
sql/vector--0.7.3--0.7.4.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- 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
|
||||
@@ -38,7 +38,7 @@
|
||||
/* F16C has better performance than _Float16 (on x86-64) */
|
||||
#if defined(__F16C__)
|
||||
#define F16C_SUPPORT
|
||||
#elif defined(__FLT16_MAX__) && !defined(HALFVEC_DISPATCH) && !defined(__FreeBSD__)
|
||||
#elif defined(__FLT16_MAX__) && !defined(HALFVEC_DISPATCH) && !defined(__FreeBSD__) && (!defined(__i386__) || defined(__SSE2__))
|
||||
#define FLT16_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
@@ -379,7 +379,13 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
|
||||
for (int lc = e->level; lc >= 0; lc--)
|
||||
{
|
||||
int lm = HnswGetLayerM(m, lc);
|
||||
HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc);
|
||||
Size neighborsSize = HNSW_NEIGHBOR_ARRAY_SIZE(lm);
|
||||
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++)
|
||||
{
|
||||
@@ -389,7 +395,6 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
|
||||
/* Keep scan-build happy on Mac x86-64 */
|
||||
Assert(neighborElement);
|
||||
|
||||
/* Use element for lock instead of hc since hc can be replaced */
|
||||
LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE);
|
||||
HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation);
|
||||
LWLockRelease(&neighborElement->lock);
|
||||
|
||||
@@ -36,14 +36,15 @@ GetInsertPage(Relation index)
|
||||
* Check for a free offset
|
||||
*/
|
||||
static bool
|
||||
HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage)
|
||||
HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size etupSize, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage)
|
||||
{
|
||||
OffsetNumber offno;
|
||||
OffsetNumber maxoffno = PageGetMaxOffsetNumber(page);
|
||||
|
||||
for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno))
|
||||
{
|
||||
HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno));
|
||||
ItemId eitemid = PageGetItemId(page, offno);
|
||||
HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, eitemid);
|
||||
|
||||
/* Skip neighbor tuples */
|
||||
if (!HnswIsElementTuple(etup))
|
||||
@@ -54,7 +55,9 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size
|
||||
BlockNumber elementPage = BufferGetBlockNumber(buf);
|
||||
BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid);
|
||||
OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid);
|
||||
ItemId itemid;
|
||||
ItemId nitemid;
|
||||
Size pageFree;
|
||||
Size npageFree;
|
||||
|
||||
if (!BlockNumberIsValid(*newInsertPage))
|
||||
*newInsertPage = elementPage;
|
||||
@@ -73,10 +76,25 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size
|
||||
*npage = BufferGetPage(*nbuf);
|
||||
}
|
||||
|
||||
itemid = PageGetItemId(*npage, neighborOffno);
|
||||
nitemid = PageGetItemId(*npage, neighborOffno);
|
||||
|
||||
/* Check for space on neighbor tuple page */
|
||||
if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize)
|
||||
/* Ensure aligned for space check */
|
||||
Assert(etupSize == MAXALIGN(etupSize));
|
||||
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;
|
||||
*freeNeighborOffno = neighborOffno;
|
||||
@@ -184,7 +202,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B
|
||||
}
|
||||
|
||||
/* Next, try space from a deleted element */
|
||||
if (HnswFreeOffset(index, buf, page, e, ntupSize, &nbuf, &npage, &freeOffno, &freeNeighborOffno, &newInsertPage))
|
||||
if (HnswFreeOffset(index, buf, page, e, etupSize, ntupSize, &nbuf, &npage, &freeOffno, &freeNeighborOffno, &newInsertPage))
|
||||
{
|
||||
if (nbuf != buf)
|
||||
{
|
||||
|
||||
11
test/perl/PostgreSQL/Test/Cluster.pm
Normal file
11
test/perl/PostgreSQL/Test/Cluster.pm
Normal file
@@ -0,0 +1,11 @@
|
||||
package PostgreSQL::Test::Cluster;
|
||||
|
||||
use PostgresNode;
|
||||
|
||||
sub new
|
||||
{
|
||||
my ($class, $name) = @_;
|
||||
return get_new_node($name);
|
||||
}
|
||||
|
||||
1;
|
||||
5
test/perl/PostgreSQL/Test/Utils.pm
Normal file
5
test/perl/PostgreSQL/Test/Utils.pm
Normal file
@@ -0,0 +1,5 @@
|
||||
package PostgreSQL::Test::Utils;
|
||||
|
||||
use TestLib;
|
||||
|
||||
1;
|
||||
@@ -1,8 +0,0 @@
|
||||
use PostgreSQL::Test::Cluster;
|
||||
|
||||
sub get_new_node
|
||||
{
|
||||
return PostgreSQL::Test::Cluster->new(@_);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,3 +0,0 @@
|
||||
use PostgreSQL::Test::Utils;
|
||||
|
||||
1;
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
# Test generic xlog record work for ivfflat index replication.
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 32;
|
||||
@@ -49,7 +49,7 @@ sub test_index_replay
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize primary node
|
||||
$node_primary = get_new_node('primary');
|
||||
$node_primary = PostgreSQL::Test::Cluster->new('primary');
|
||||
$node_primary->init(allows_streaming => 1);
|
||||
if ($dim > 32)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ my $backup_name = 'my_backup';
|
||||
$node_primary->backup($backup_name);
|
||||
|
||||
# Create streaming replica linking to primary
|
||||
$node_replica = get_new_node('replica');
|
||||
$node_replica = PostgreSQL::Test::Cluster->new('replica');
|
||||
$node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1);
|
||||
$node_replica->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 3;
|
||||
@@ -15,7 +15,7 @@ for (1 .. $dim)
|
||||
my $array_sql = join(", ", @r);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -49,7 +49,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 768;
|
||||
@@ -9,7 +9,7 @@ my $dim = 768;
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 3;
|
||||
@@ -11,7 +11,7 @@ my $limit = 20;
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
# Test generic xlog record work for hnsw index replication.
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 32;
|
||||
@@ -49,7 +49,7 @@ sub test_index_replay
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize primary node
|
||||
$node_primary = get_new_node('primary');
|
||||
$node_primary = PostgreSQL::Test::Cluster->new('primary');
|
||||
$node_primary->init(allows_streaming => 1);
|
||||
if ($dim > 32)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ my $backup_name = 'my_backup';
|
||||
$node_primary->backup($backup_name);
|
||||
|
||||
# Create streaming replica linking to primary
|
||||
$node_replica = get_new_node('replica');
|
||||
$node_replica = PostgreSQL::Test::Cluster->new('replica');
|
||||
$node_replica->init_from_backup($node_primary, $backup_name, has_streaming => 1);
|
||||
$node_replica->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 3;
|
||||
@@ -15,7 +15,7 @@ for (1 .. $dim)
|
||||
my $array_sql = join(", ", @r);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -47,7 +47,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -47,7 +47,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Ensures elements and neighbors on both same and different pages
|
||||
@@ -10,7 +10,7 @@ my $dim = 1900;
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 3;
|
||||
@@ -11,7 +11,7 @@ my $limit = 20;
|
||||
my $array_sql = join(",", ('random()') x $dim);
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
@@ -53,7 +53,7 @@ sub test_aggregate
|
||||
else
|
||||
{
|
||||
# Does not raise overflow error in this instance due to loss of precision
|
||||
is($res, "[24576,24576,49152]")
|
||||
is($res, "[24576,24576,49152]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $dim = 1024;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -51,7 +51,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -51,7 +51,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -51,7 +51,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -47,7 +47,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -47,7 +47,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -48,7 +48,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -51,7 +51,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
my $array_sql = join(",", ('floor(random() * 2)::int - 1') x 3);
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -10,7 +10,7 @@ my $dim = 5;
|
||||
my $array_sql = join(",", ('floor(random() * 4)::int - 2') x $dim);
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
my $node;
|
||||
@@ -51,7 +51,7 @@ sub test_recall
|
||||
}
|
||||
|
||||
# Initialize node
|
||||
$node = get_new_node('node');
|
||||
$node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
# Initialize node
|
||||
my $node = get_new_node('node');
|
||||
my $node = PostgreSQL::Test::Cluster->new('node');
|
||||
$node->init;
|
||||
$node->start;
|
||||
|
||||
|
||||
42
test/t/038_hnsw_sparsevec_vacuum_insert.pl
Normal file
42
test/t/038_hnsw_sparsevec_vacuum_insert.pl
Normal file
@@ -0,0 +1,42 @@
|
||||
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();
|
||||
@@ -1,4 +1,4 @@
|
||||
comment = 'vector data type and ivfflat and hnsw access methods'
|
||||
default_version = '0.7.2'
|
||||
default_version = '0.7.4'
|
||||
module_pathname = '$libdir/vector'
|
||||
relocatable = true
|
||||
|
||||
Reference in New Issue
Block a user