mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 03:57:34 +08:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e14fa82626 | ||
|
|
2ae4de83fe | ||
|
|
5d2c4883dc | ||
|
|
fc1de9806a | ||
|
|
e375dd33f3 | ||
|
|
b643ef637a | ||
|
|
0ee5bfda65 | ||
|
|
c5bec2a534 | ||
|
|
40f65dc8ba | ||
|
|
9ec174137f | ||
|
|
423e478a85 | ||
|
|
8b301197fe | ||
|
|
c02feaa9ad | ||
|
|
729374a9b8 | ||
|
|
a8245d6cda | ||
|
|
5220a6ec7e | ||
|
|
ddd873f369 | ||
|
|
8735c4782a | ||
|
|
17ec3f3852 | ||
|
|
8df12a62e7 | ||
|
|
647c9002be | ||
|
|
3e6345f02a | ||
|
|
2b3484ddcd | ||
|
|
1a6debf281 | ||
|
|
bff4d7ea68 | ||
|
|
d5b979e4fa | ||
|
|
d52426b3fa | ||
|
|
b125b2debb | ||
|
|
3d7186a17c | ||
|
|
58ba2139ce |
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@@ -2,7 +2,6 @@ name: build
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
build:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -11,7 +10,7 @@ jobs:
|
||||
postgres: [14, 13, 12, 11, 10, 9.6]
|
||||
include:
|
||||
- os: macos-latest
|
||||
postgres: 13
|
||||
postgres: 14
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ankane/setup-postgres@v1
|
||||
@@ -34,6 +33,6 @@ jobs:
|
||||
- if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
run: |
|
||||
brew install cpanm && cpanm IPC::Run
|
||||
wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_13_2.tar.gz
|
||||
tar xf REL_13_2.tar.gz
|
||||
make prove_installcheck PROVE=prove PERL5LIB=postgres-REL_13_2/src/test/perl
|
||||
wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_14_1.tar.gz
|
||||
tar xf REL_14_1.tar.gz
|
||||
make prove_installcheck PROVE=prove PERL5LIB=postgres-REL_14_1/src/test/perl
|
||||
|
||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,3 +1,16 @@
|
||||
## 0.2.3 (2022-01-30)
|
||||
|
||||
- Added build progress for Postgres 12+
|
||||
- Improved interrupt handling during index creation
|
||||
|
||||
## 0.2.2 (2022-01-15)
|
||||
|
||||
- Fixed compilation error on Mac ARM
|
||||
|
||||
## 0.2.1 (2022-01-02)
|
||||
|
||||
- Fixed `operator is not unique` error
|
||||
|
||||
## 0.2.0 (2021-10-03)
|
||||
|
||||
- Added support for Postgres 14
|
||||
|
||||
12
META.json
12
META.json
@@ -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.2.0",
|
||||
"version": "0.2.3",
|
||||
"maintainer": [
|
||||
"Andrew Kane <andrew@ankane.org>"
|
||||
],
|
||||
@@ -20,18 +20,18 @@
|
||||
"vector": {
|
||||
"file": "sql/vector.sql",
|
||||
"docfile": "README.md",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.3",
|
||||
"abstract": "Open-source vector similarity search for Postgres"
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"homepage": "https://github.com/ankane/pgvector",
|
||||
"homepage": "https://github.com/pgvector/pgvector",
|
||||
"bugtracker": {
|
||||
"web": "https://github.com/ankane/pgvector/issues"
|
||||
"web": "https://github.com/pgvector/pgvector/issues"
|
||||
},
|
||||
"repository": {
|
||||
"url": "https://github.com/ankane/pgvector.git",
|
||||
"web": "https://github.com/ankane/pgvector",
|
||||
"url": "https://github.com/pgvector/pgvector.git",
|
||||
"web": "https://github.com/pgvector/pgvector",
|
||||
"type": "git"
|
||||
}
|
||||
},
|
||||
|
||||
14
Makefile
14
Makefile
@@ -1,5 +1,5 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.2.0
|
||||
EXTVERSION = 0.2.3
|
||||
|
||||
MODULE_big = vector
|
||||
DATA = $(wildcard sql/*--*.sql)
|
||||
@@ -11,6 +11,13 @@ REGRESS_OPTS = --inputdir=test
|
||||
|
||||
OPTFLAGS = -march=native
|
||||
|
||||
# Mac ARM doesn't support -march=native
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
ifeq ($(shell uname -p), arm)
|
||||
OPTFLAGS =
|
||||
endif
|
||||
endif
|
||||
|
||||
# For auto-vectorization:
|
||||
# - GCC (needs -ftree-vectorize OR -O3) - https://gcc.gnu.org/projects/tree-ssa/vectorization.html
|
||||
# - Clang (could use pragma instead) - https://llvm.org/docs/Vectorizers.html
|
||||
@@ -42,3 +49,8 @@ prove_installcheck:
|
||||
dist:
|
||||
mkdir -p dist
|
||||
git archive --format zip --prefix=$(EXTENSION)-$(EXTVERSION)/ --output dist/$(EXTENSION)-$(EXTVERSION).zip master
|
||||
|
||||
.PHONY: docker
|
||||
|
||||
docker:
|
||||
docker build --pull --no-cache -t ankane/pgvector:latest .
|
||||
|
||||
103
README.md
103
README.md
@@ -4,20 +4,20 @@ Open-source vector similarity search for Postgres
|
||||
|
||||
```sql
|
||||
CREATE TABLE table (column vector(3));
|
||||
CREATE INDEX ON table USING ivfflat (column);
|
||||
CREATE INDEX ON table USING ivfflat (column vector_l2_ops);
|
||||
SELECT * FROM table ORDER BY column <-> '[1,2,3]' LIMIT 5;
|
||||
```
|
||||
|
||||
Supports L2 distance, inner product, and cosine distance
|
||||
|
||||
[](https://github.com/ankane/pgvector/actions)
|
||||
[](https://github.com/pgvector/pgvector/actions)
|
||||
|
||||
## Installation
|
||||
|
||||
Compile and install the extension (supports Postgres 9.6+)
|
||||
|
||||
```sh
|
||||
git clone --branch v0.2.0 https://github.com/ankane/pgvector.git
|
||||
git clone --branch v0.2.3 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
make install # may need sudo
|
||||
@@ -62,7 +62,7 @@ Speed up queries with an approximate index. Add an index for each distance funct
|
||||
L2 distance
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON table USING ivfflat (column);
|
||||
CREATE INDEX ON table USING ivfflat (column vector_l2_ops);
|
||||
```
|
||||
|
||||
Inner product
|
||||
@@ -77,16 +77,30 @@ Cosine distance
|
||||
CREATE INDEX ON table USING ivfflat (column vector_cosine_ops);
|
||||
```
|
||||
|
||||
Indexes should be created after the table has data for optimal clustering. Also, unlike typical indexes which only affect performance, you may see different results for queries after adding an approximate index.
|
||||
Indexes should be created after the table has data for optimal clustering. If the distribution of data changes significantly, you can reindex without downtime:
|
||||
|
||||
```sql
|
||||
-- Postgres 12+
|
||||
REINDEX INDEX CONCURRENTLY index_name;
|
||||
|
||||
-- Postgres < 12
|
||||
CREATE INDEX CONCURRENTLY temp_name ON table USING ivfflat (column opclass);
|
||||
DROP INDEX CONCURRENTLY index_name;
|
||||
ALTER INDEX temp_name RENAME TO index_name;
|
||||
```
|
||||
|
||||
Also, unlike typical indexes which only affect performance, you may see different results for queries after adding an approximate index.
|
||||
|
||||
### Index Options
|
||||
|
||||
Specify the number of inverted lists (100 by default)
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON table USING ivfflat (column) WITH (lists = 100);
|
||||
CREATE INDEX ON table USING ivfflat (column opclass) WITH (lists = 100);
|
||||
```
|
||||
|
||||
A [good place to start](https://github.com/facebookresearch/faiss/issues/112) is `4 * sqrt(rows)`
|
||||
|
||||
### Query Options
|
||||
|
||||
Specify the number of probes (1 by default)
|
||||
@@ -106,16 +120,48 @@ SELECT ...
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
### Indexing Progress [unreleased]
|
||||
|
||||
Check [indexing progress](https://www.postgresql.org/docs/current/progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING) with Postgres 12+
|
||||
|
||||
```sql
|
||||
SELECT phase, tuples_done, tuples_total FROM pg_stat_progress_create_index;
|
||||
```
|
||||
|
||||
The phases are:
|
||||
|
||||
1. `initializing`
|
||||
2. `sampling table`
|
||||
3. `performing k-means`
|
||||
4. `sorting tuples`
|
||||
5. `loading tuples`
|
||||
|
||||
Note: `tuples_done` and `tuples_total` are only populated during the `loading tuples` phase
|
||||
|
||||
### Partial Indexes
|
||||
|
||||
Consider [partial indexes](https://www.postgresql.org/docs/current/indexes-partial.html) for queries with a `WHERE` clause
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON table USING ivfflat (column) WHERE (other_column = 123);
|
||||
CREATE INDEX ON table USING ivfflat (column opclass) WHERE (other_column = 123);
|
||||
```
|
||||
|
||||
To index many different values of `other_column`, consider [partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html) on `other_column`.
|
||||
|
||||
## Performance
|
||||
|
||||
To speed up queries without an index, increase `max_parallel_workers_per_gather`.
|
||||
|
||||
```sql
|
||||
SET max_parallel_workers_per_gather = 4;
|
||||
```
|
||||
|
||||
To speed up queries with an index, increase the number of inverted lists (at the expense of recall).
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON table USING ivfflat (column opclass) WITH (lists = 1000);
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Vector Type
|
||||
@@ -146,18 +192,35 @@ vector_norm(vector) | Euclidean norm
|
||||
|
||||
Libraries that use pgvector:
|
||||
|
||||
- [pgvector-python](https://github.com/ankane/pgvector-python) (Python)
|
||||
- [pgvector-python](https://github.com/pgvector/pgvector-python) (Python)
|
||||
- [Neighbor](https://github.com/ankane/neighbor) (Ruby)
|
||||
- [pgvector-node](https://github.com/ankane/pgvector-node) (Node.js)
|
||||
- [pgvector-go](https://github.com/ankane/pgvector-go) (Go)
|
||||
- [pgvector-rust](https://github.com/ankane/pgvector-rust) (Rust)
|
||||
- [pgvector-cpp](https://github.com/ankane/pgvector-cpp) (C++)
|
||||
- [pgvector-node](https://github.com/pgvector/pgvector-node) (Node.js)
|
||||
- [pgvector-go](https://github.com/pgvector/pgvector-go) (Go)
|
||||
- [pgvector-rust](https://github.com/pgvector/pgvector-rust) (Rust)
|
||||
- [pgvector-cpp](https://github.com/pgvector/pgvector-cpp) (C++)
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
#### How many vectors can be stored in a single table?
|
||||
|
||||
A non-partitioned table has a limit of 32 TB by default in Postgres. A partitioned table can have thousands of partitions of that size.
|
||||
|
||||
#### Is replication supported?
|
||||
|
||||
Yes, pgvector uses the write-ahead log (WAL), which allows for replication and point-in-time recovery.
|
||||
|
||||
#### What if my data has more than 1024 dimensions?
|
||||
|
||||
Two things you can try are:
|
||||
|
||||
1. use dimensionality reduction
|
||||
2. compile Postgres with a larger block size (`./configure --with-blocksize=32`) and edit the limit in `src/vector.h`
|
||||
|
||||
## Additional Installation Methods
|
||||
|
||||
### Docker
|
||||
|
||||
Get the [Docker image](https://hub.docker.com/repository/docker/ankane/pgvector) with:
|
||||
Get the [Docker image](https://hub.docker.com/r/ankane/pgvector) with:
|
||||
|
||||
```sh
|
||||
docker pull ankane/pgvector
|
||||
@@ -168,7 +231,7 @@ This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres).
|
||||
You can also build the image manually
|
||||
|
||||
```sh
|
||||
git clone --branch v0.2.0 https://github.com/ankane/pgvector.git
|
||||
git clone --branch v0.2.3 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
docker build -t pgvector .
|
||||
```
|
||||
@@ -178,7 +241,7 @@ docker build -t pgvector .
|
||||
On Mac with Homebrew Postgres, you can use:
|
||||
|
||||
```sh
|
||||
brew install ankane/brew/pgvector
|
||||
brew install pgvector/brew/pgvector
|
||||
```
|
||||
|
||||
### PGXN
|
||||
@@ -195,7 +258,7 @@ Some Postgres providers only support specific extensions. To request a new exten
|
||||
|
||||
- Amazon RDS - follow the instructions on [this page](https://aws.amazon.com/rds/postgresql/faqs/)
|
||||
- Google Cloud SQL - follow the instructions on [this page](https://cloud.google.com/sql/docs/postgres/extensions#requesting-support-for-a-new-extension)
|
||||
- DigitalOcean Managed Databases - follow the instructions on [this page](https://docs.digitalocean.com/products/databases/postgresql/resources/supported-extensions/#supported-extensions)
|
||||
- DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/app-framework-services/p/pgvector-extension-for-postgresql)
|
||||
- Azure Database for PostgreSQL - follow the instructions on [this page](https://docs.microsoft.com/en-us/azure/postgresql/concepts-extensions#next-steps)
|
||||
|
||||
## Upgrading
|
||||
@@ -218,21 +281,21 @@ Thanks to:
|
||||
|
||||
## History
|
||||
|
||||
View the [changelog](https://github.com/ankane/pgvector/blob/master/CHANGELOG.md)
|
||||
View the [changelog](https://github.com/pgvector/pgvector/blob/master/CHANGELOG.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
||||
|
||||
- [Report bugs](https://github.com/ankane/pgvector/issues)
|
||||
- Fix bugs and [submit pull requests](https://github.com/ankane/pgvector/pulls)
|
||||
- [Report bugs](https://github.com/pgvector/pgvector/issues)
|
||||
- Fix bugs and [submit pull requests](https://github.com/pgvector/pgvector/pulls)
|
||||
- Write, clarify, or fix documentation
|
||||
- Suggest or add new features
|
||||
|
||||
To get started with development:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/ankane/pgvector.git
|
||||
git clone https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
make install
|
||||
|
||||
19
sql/vector--0.2.0--0.2.1.sql
Normal file
19
sql/vector--0.2.0--0.2.1.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION vector UPDATE TO '0.2.1'" to load this file. \quit
|
||||
|
||||
DROP CAST (integer[] AS vector);
|
||||
DROP CAST (real[] AS vector);
|
||||
DROP CAST (double precision[] AS vector);
|
||||
DROP CAST (numeric[] AS vector);
|
||||
|
||||
CREATE CAST (integer[] AS vector)
|
||||
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (real[] AS vector)
|
||||
WITH FUNCTION array_to_vector(real[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (double precision[] AS vector)
|
||||
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (numeric[] AS vector)
|
||||
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS ASSIGNMENT;
|
||||
2
sql/vector--0.2.1--0.2.2.sql
Normal file
2
sql/vector--0.2.1--0.2.2.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.2.2'" to load this file. \quit
|
||||
2
sql/vector--0.2.2--0.2.3.sql
Normal file
2
sql/vector--0.2.2--0.2.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.2.3'" to load this file. \quit
|
||||
@@ -108,21 +108,21 @@ CREATE FUNCTION vector_to_float4(vector, integer, boolean) RETURNS real[]
|
||||
CREATE CAST (vector AS vector)
|
||||
WITH FUNCTION vector(vector, integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (integer[] AS vector)
|
||||
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (real[] AS vector)
|
||||
WITH FUNCTION array_to_vector(real[], integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (double precision[] AS vector)
|
||||
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (numeric[] AS vector)
|
||||
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (vector AS real[])
|
||||
WITH FUNCTION vector_to_float4(vector, integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE CAST (integer[] AS vector)
|
||||
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (real[] AS vector)
|
||||
WITH FUNCTION array_to_vector(real[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (double precision[] AS vector)
|
||||
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
CREATE CAST (numeric[] AS vector)
|
||||
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS ASSIGNMENT;
|
||||
|
||||
-- operators
|
||||
|
||||
CREATE OPERATOR <-> (
|
||||
|
||||
@@ -7,8 +7,19 @@
|
||||
#include "miscadmin.h"
|
||||
#include "storage/bufmgr.h"
|
||||
|
||||
#if PG_VERSION_NUM >= 140000
|
||||
#include "utils/backend_progress.h"
|
||||
#elif PG_VERSION_NUM >= 120000
|
||||
#include "pgstat.h"
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
#include "access/tableam.h"
|
||||
#include "commands/progress.h"
|
||||
#else
|
||||
#define PROGRESS_CREATEIDX_SUBPHASE 0
|
||||
#define PROGRESS_CREATEIDX_TUPLES_TOTAL 0
|
||||
#define PROGRESS_CREATEIDX_TUPLES_DONE 0
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM >= 110000
|
||||
@@ -25,6 +36,17 @@
|
||||
#define CALLBACK_ITEM_POINTER HeapTuple hup
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update build phase progress
|
||||
*/
|
||||
static inline void
|
||||
UpdateProgress(int index, int64 val)
|
||||
{
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
pgstat_progress_update_param(index, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for sampling
|
||||
*/
|
||||
@@ -82,6 +104,8 @@ SampleRows(IvfflatBuildState * buildstate)
|
||||
int targsamples = buildstate->samples->maxlen;
|
||||
BlockNumber totalblocks = RelationGetNumberOfBlocks(buildstate->heap);
|
||||
|
||||
UpdateProgress(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_SAMPLE);
|
||||
|
||||
buildstate->rowstoskip = -1;
|
||||
|
||||
BlockSampler_Init(&buildstate->bs, totalblocks, targsamples, random());
|
||||
@@ -165,6 +189,8 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values,
|
||||
* need not save it.
|
||||
*/
|
||||
tuplesort_puttupleslot(buildstate->sortstate, slot);
|
||||
|
||||
buildstate->indtuples++;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -212,6 +238,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum)
|
||||
BlockNumber insertPage = InvalidBlockNumber;
|
||||
Size itemsz;
|
||||
int i;
|
||||
int64 inserted = 0;
|
||||
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc, &TTSOpsMinimalTuple);
|
||||
@@ -220,10 +247,18 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum)
|
||||
#endif
|
||||
TupleDesc tupdesc = RelationGetDescr(index);
|
||||
|
||||
UpdateProgress(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_LOAD);
|
||||
|
||||
UpdateProgress(PROGRESS_CREATEIDX_TUPLES_TOTAL, buildstate->indtuples);
|
||||
|
||||
GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list);
|
||||
|
||||
for (i = 0; i < buildstate->centers->length; i++)
|
||||
{
|
||||
/* Can take a while, so ensure we can interrupt */
|
||||
/* Needs to be called when no buffer locks are held */
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
buf = IvfflatNewBuffer(index, forkNum);
|
||||
IvfflatInitPage(index, &buf, &page, &state);
|
||||
|
||||
@@ -243,7 +278,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum)
|
||||
|
||||
pfree(itup);
|
||||
|
||||
buildstate->indtuples += 1;
|
||||
UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++inserted);
|
||||
|
||||
GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list);
|
||||
}
|
||||
@@ -283,6 +318,12 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In
|
||||
buildstate->kmeansnormprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC);
|
||||
buildstate->collation = index->rd_indcollation[0];
|
||||
|
||||
/* Require more than one dimension for spherical k-means */
|
||||
/* Lists check for backwards compatibility */
|
||||
/* TODO Remove lists check in 0.3.0 */
|
||||
if (buildstate->kmeansnormprocinfo != NULL && buildstate->dimensions == 1 && buildstate->lists > 1)
|
||||
elog(ERROR, "dimensions must be greater than one for this opclass");
|
||||
|
||||
/* Create tuple description for sorting */
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
buildstate->tupdesc = CreateTemplateTupleDesc(4);
|
||||
@@ -342,6 +383,7 @@ ComputeCenters(IvfflatBuildState * buildstate)
|
||||
SampleRows(buildstate);
|
||||
|
||||
/* Calculate centers */
|
||||
UpdateProgress(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_KMEANS);
|
||||
IvfflatKmeans(buildstate->index, buildstate->samples, buildstate->centers);
|
||||
|
||||
/* Free samples before we allocate more memory */
|
||||
@@ -432,6 +474,8 @@ CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum)
|
||||
Oid sortCollations[] = {InvalidOid};
|
||||
bool nullsFirstFlags[] = {false};
|
||||
|
||||
UpdateProgress(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_SORT);
|
||||
|
||||
#if PG_VERSION_NUM >= 110000
|
||||
buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, maintenance_work_mem, NULL, false);
|
||||
#else
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include "utils/guc.h"
|
||||
#include "utils/selfuncs.h"
|
||||
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
#include "commands/progress.h"
|
||||
#endif
|
||||
|
||||
int ivfflat_probes;
|
||||
static relopt_kind ivfflat_relopt_kind;
|
||||
|
||||
@@ -30,6 +34,31 @@ _PG_init(void)
|
||||
1, 1, IVFFLAT_MAX_LISTS, PGC_USERSET, 0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the name of index build phase
|
||||
*/
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
static char *
|
||||
ivfflatbuildphasename(int64 phasenum)
|
||||
{
|
||||
switch (phasenum)
|
||||
{
|
||||
case PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE:
|
||||
return "initializing";
|
||||
case PROGRESS_IVFFLAT_PHASE_SAMPLE:
|
||||
return "sampling table";
|
||||
case PROGRESS_IVFFLAT_PHASE_KMEANS:
|
||||
return "performing k-means";
|
||||
case PROGRESS_IVFFLAT_PHASE_SORT:
|
||||
return "sorting tuples";
|
||||
case PROGRESS_IVFFLAT_PHASE_LOAD:
|
||||
return "loading tuples";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Estimate the cost of an index scan
|
||||
*/
|
||||
@@ -174,7 +203,7 @@ ivfflathandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amoptions = ivfflatoptions;
|
||||
amroutine->amproperty = NULL; /* TODO AMPROP_DISTANCE_ORDERABLE */
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->ambuildphasename = ivfflatbuildphasename;
|
||||
#endif
|
||||
amroutine->amvalidate = ivfflatvalidate;
|
||||
amroutine->ambeginscan = ivfflatbeginscan;
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
#define IVFFLAT_DEFAULT_LISTS 100
|
||||
#define IVFFLAT_MAX_LISTS 32768
|
||||
|
||||
/* Build phases */
|
||||
/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */
|
||||
#define PROGRESS_IVFFLAT_PHASE_SAMPLE 2
|
||||
#define PROGRESS_IVFFLAT_PHASE_KMEANS 3
|
||||
#define PROGRESS_IVFFLAT_PHASE_SORT 4
|
||||
#define PROGRESS_IVFFLAT_PHASE_LOAD 5
|
||||
|
||||
#define IVFFLAT_LIST_SIZE(_dim) (offsetof(IvfflatListData, center) + VECTOR_SIZE(_dim))
|
||||
|
||||
#define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque) PageGetSpecialPointer(page))
|
||||
|
||||
@@ -42,3 +42,10 @@ SELECT '[1,2,3]'::vector::real[];
|
||||
|
||||
SELECT array_agg(n)::vector FROM generate_series(1, 1025) n;
|
||||
ERROR: vector cannot have more than 1024 dimensions
|
||||
-- ensure no error
|
||||
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];
|
||||
?column?
|
||||
----------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
|
||||
@@ -12,3 +12,6 @@ SELECT '{-Infinity}'::real[]::vector;
|
||||
SELECT '{}'::real[]::vector;
|
||||
SELECT '[1,2,3]'::vector::real[];
|
||||
SELECT array_agg(n)::vector FROM generate_series(1, 1025) n;
|
||||
|
||||
-- ensure no error
|
||||
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
comment = 'vector data type and ivfflat access method'
|
||||
default_version = '0.2.0'
|
||||
default_version = '0.2.3'
|
||||
module_pathname = '$libdir/vector'
|
||||
relocatable = true
|
||||
|
||||
Reference in New Issue
Block a user