mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 12:07:34 +08:00
Compare commits
1 Commits
v0.7.4
...
hnsw-stats
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bc29ac697 |
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -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:
|
||||||
|
|||||||
17
Makefile.win
17
Makefile.win
@@ -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
|
||||||
|
|||||||
@@ -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 .
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package PostgreSQL::Test::Cluster;
|
|
||||||
|
|
||||||
use PostgresNode;
|
|
||||||
|
|
||||||
sub new
|
|
||||||
{
|
|
||||||
my ($class, $name) = @_;
|
|
||||||
return get_new_node($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package PostgreSQL::Test::Utils;
|
|
||||||
|
|
||||||
use TestLib;
|
|
||||||
|
|
||||||
1;
|
|
||||||
8
test/perl/PostgresNode.pm
Normal file
8
test/perl/PostgresNode.pm
Normal 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
3
test/perl/TestLib.pm
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
use PostgreSQL::Test::Utils;
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user