mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-23 04:20:56 +08:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38be81cf20 | ||
|
|
62cc3398ed | ||
|
|
af86392a34 | ||
|
|
a9067a8101 | ||
|
|
6deca154e6 | ||
|
|
6342439eb8 | ||
|
|
21967765a3 | ||
|
|
d31b7e3997 | ||
|
|
efa85aaba1 | ||
|
|
3c820b5a50 | ||
|
|
199c0e5e34 | ||
|
|
bcab0ad8ae | ||
|
|
09e95fc8f9 | ||
|
|
6119cced74 | ||
|
|
f8c07edba1 | ||
|
|
baabbaeff9 | ||
|
|
f0993282fe | ||
|
|
01584d3df6 | ||
|
|
6f50c4f5bd | ||
|
|
31a953f8db | ||
|
|
7b3d0f2595 | ||
|
|
099b9e9027 | ||
|
|
e1f3caba49 | ||
|
|
3f0d2bbd2f | ||
|
|
c989b85f75 | ||
|
|
a9bbee4198 | ||
|
|
fb274f1197 | ||
|
|
88ba5da6a7 | ||
|
|
6a550c8b52 | ||
|
|
5748cb6b43 | ||
|
|
60814b8f39 | ||
|
|
773a63bed1 | ||
|
|
955a5a6082 | ||
|
|
8863920fdc | ||
|
|
6d9653d763 | ||
|
|
3a488c9f2f | ||
|
|
fe133bfe5d | ||
|
|
e279bb3d7e | ||
|
|
0aa39a8c0c |
25
.github/workflows/build.yml
vendored
25
.github/workflows/build.yml
vendored
@@ -3,20 +3,37 @@ on: [push, pull_request]
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
postgres: [13, 12, 11, 10, 9.6]
|
postgres: [13, 12, 11, 10, 9.6]
|
||||||
|
include:
|
||||||
|
- os: macos-latest
|
||||||
|
postgres: 13
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ankane/setup-postgres@v1
|
- uses: ankane/setup-postgres@v1
|
||||||
with:
|
with:
|
||||||
postgres-version: ${{ matrix.postgres }}
|
postgres-version: ${{ matrix.postgres }}
|
||||||
- run: sudo apt-get update && sudo apt-get install postgresql-server-dev-${{ matrix.postgres }} libipc-run-perl
|
- if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||||
|
run: sudo apt-get update && sudo apt-get install postgresql-server-dev-${{ matrix.postgres }} libipc-run-perl
|
||||||
- run: make
|
- run: make
|
||||||
- run: |
|
- if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||||
|
run: |
|
||||||
export PG_CONFIG=`which pg_config`
|
export PG_CONFIG=`which pg_config`
|
||||||
sudo --preserve-env=PG_CONFIG make install
|
sudo --preserve-env=PG_CONFIG make install
|
||||||
|
- if: ${{ startsWith(matrix.os, 'macos') }}
|
||||||
|
run: make install
|
||||||
- run: make installcheck
|
- run: make installcheck
|
||||||
- run: make prove_installcheck
|
- if: ${{ failure() }}
|
||||||
|
run: cat regression.diffs
|
||||||
|
- if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||||
|
run: make prove_installcheck
|
||||||
|
- 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
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
results
|
/dist/
|
||||||
tmp_check
|
/results/
|
||||||
|
/tmp_check/
|
||||||
|
/sql/vector--?.?.?.sql
|
||||||
regression.*
|
regression.*
|
||||||
*.o
|
*.o
|
||||||
*.so
|
*.so
|
||||||
|
|||||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
|||||||
|
## 0.1.3 (2021-05-06)
|
||||||
|
|
||||||
|
- Added Dockerfile
|
||||||
|
- Fixed version
|
||||||
|
|
||||||
|
## 0.1.2 (2021-04-26)
|
||||||
|
|
||||||
|
- Vectorized distance calculations
|
||||||
|
- Improved cost estimation
|
||||||
|
|
||||||
## 0.1.1 (2021-04-25)
|
## 0.1.1 (2021-04-25)
|
||||||
|
|
||||||
- Added binary representation for `COPY`
|
- Added binary representation for `COPY`
|
||||||
|
|||||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM postgres
|
||||||
|
|
||||||
|
COPY . /tmp/pgvector
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends build-essential postgresql-server-dev-13 && \
|
||||||
|
cd /tmp/pgvector && \
|
||||||
|
make clean && \
|
||||||
|
make OPTFLAGS="" && \
|
||||||
|
make install && \
|
||||||
|
mkdir /usr/share/doc/pgvector && \
|
||||||
|
cp LICENSE README.md /usr/share/doc/pgvector && \
|
||||||
|
rm -r /tmp/pgvector && \
|
||||||
|
apt-get remove -y build-essential postgresql-server-dev-13 && \
|
||||||
|
apt-get autoremove -y && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
49
META.json
Normal file
49
META.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "vector",
|
||||||
|
"abstract": "Open-source vector similarity search for Postgres",
|
||||||
|
"description": "Supports L2 distance, inner product, and cosine distance",
|
||||||
|
"version": "0.1.3",
|
||||||
|
"maintainer": [
|
||||||
|
"Andrew Kane <andrew@ankane.org>"
|
||||||
|
],
|
||||||
|
"license": {
|
||||||
|
"PostgreSQL": "http://www.postgresql.org/about/licence"
|
||||||
|
},
|
||||||
|
"prereqs": {
|
||||||
|
"runtime": {
|
||||||
|
"requires": {
|
||||||
|
"PostgreSQL": "9.6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provides": {
|
||||||
|
"vector": {
|
||||||
|
"file": "sql/vector.sql",
|
||||||
|
"docfile": "README.md",
|
||||||
|
"version": "0.1.3",
|
||||||
|
"abstract": "Open-source vector similarity search for Postgres"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"homepage": "https://github.com/ankane/pgvector",
|
||||||
|
"bugtracker": {
|
||||||
|
"web": "https://github.com/ankane/pgvector/issues"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"url": "https://github.com/ankane/pgvector.git",
|
||||||
|
"web": "https://github.com/ankane/pgvector",
|
||||||
|
"type": "git"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"generated_by": "Andrew Kane",
|
||||||
|
"meta-spec": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"url": "http://pgxn.org/meta/spec.txt"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"vectors",
|
||||||
|
"datatype",
|
||||||
|
"nearest neighbor search",
|
||||||
|
"approximate nearest neighbors"
|
||||||
|
]
|
||||||
|
}
|
||||||
36
Makefile
36
Makefile
@@ -1,11 +1,33 @@
|
|||||||
EXTENSION = vector
|
EXTENSION = vector
|
||||||
DATA = vector--0.1.1.sql vector--0.1.0--0.1.1.sql
|
EXTVERSION = 0.1.3
|
||||||
|
|
||||||
MODULE_big = vector
|
MODULE_big = vector
|
||||||
|
DATA = $(wildcard sql/*--*.sql)
|
||||||
OBJS = src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/vector.o
|
OBJS = src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/vector.o
|
||||||
|
|
||||||
TESTS = $(wildcard sql/*.sql)
|
TESTS = $(wildcard test/sql/*.sql)
|
||||||
|
REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
|
||||||
|
REGRESS_OPTS = --inputdir=test
|
||||||
|
|
||||||
REGRESS = btree cast copy functions ivfflat_cosine ivfflat_ip ivfflat_l2 ivfflat_unlogged vector
|
OPTFLAGS = -march=native
|
||||||
|
|
||||||
|
# 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
|
||||||
|
PG_CFLAGS = $(OPTFLAGS) -ftree-vectorize -fassociative-math -fno-signed-zeros -fno-trapping-math
|
||||||
|
|
||||||
|
# Debug GCC auto-vectorization
|
||||||
|
# PG_CFLAGS += -fopt-info-vec
|
||||||
|
|
||||||
|
# Debug Clang auto-vectorization
|
||||||
|
# PG_CFLAGS += -Rpass=loop-vectorize -Rpass-analysis=loop-vectorize
|
||||||
|
|
||||||
|
all: sql/$(EXTENSION)--$(EXTVERSION).sql
|
||||||
|
|
||||||
|
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
|
||||||
|
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)
|
||||||
@@ -13,4 +35,10 @@ include $(PGXS)
|
|||||||
|
|
||||||
prove_installcheck:
|
prove_installcheck:
|
||||||
rm -rf $(CURDIR)/tmp_check
|
rm -rf $(CURDIR)/tmp_check
|
||||||
cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
|
cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),test/t/*.pl)
|
||||||
|
|
||||||
|
.PHONY: dist
|
||||||
|
|
||||||
|
dist:
|
||||||
|
mkdir -p dist
|
||||||
|
git archive --format zip --prefix=$(EXTENSION)-$(EXTVERSION)/ --output dist/$(EXTENSION)-$(EXTVERSION).zip master
|
||||||
|
|||||||
58
README.md
58
README.md
@@ -17,7 +17,7 @@ Supports L2 distance, inner product, and cosine distance
|
|||||||
Compile and install the extension (supports Postgres 9.6+)
|
Compile and install the extension (supports Postgres 9.6+)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone --branch v0.1.1 https://github.com/ankane/pgvector.git
|
git clone --branch v0.1.3 https://github.com/ankane/pgvector.git
|
||||||
cd pgvector
|
cd pgvector
|
||||||
make
|
make
|
||||||
make install # may need sudo
|
make install # may need sudo
|
||||||
@@ -29,6 +29,8 @@ Then load it in databases where you want to use it
|
|||||||
CREATE EXTENSION vector;
|
CREATE EXTENSION vector;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also install it with [Docker](#docker), [Homebrew](#homebrew), or [PGXN](#pgxn)
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Create a vector column with 3 dimensions (replace `table` and `column` with non-reserved names)
|
Create a vector column with 3 dimensions (replace `table` and `column` with non-reserved names)
|
||||||
@@ -136,11 +138,55 @@ Libraries that use pgvector:
|
|||||||
|
|
||||||
- [Neighbor](https://github.com/ankane/neighbor) (Ruby)
|
- [Neighbor](https://github.com/ankane/neighbor) (Ruby)
|
||||||
|
|
||||||
|
## Additional Installation Methods
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Get the [Docker image](https://hub.docker.com/repository/docker/ankane/pgvector) with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker pull ankane/pgvector
|
||||||
|
```
|
||||||
|
|
||||||
|
This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres).
|
||||||
|
|
||||||
|
You can also build the image manually
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone --branch v0.1.3 https://github.com/ankane/pgvector.git
|
||||||
|
cd pgvector
|
||||||
|
docker build -t pgvector .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Homebrew
|
||||||
|
|
||||||
|
On Mac with Homebrew Postgres, you can use:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install ankane/brew/pgvector
|
||||||
|
```
|
||||||
|
|
||||||
|
### PGXN
|
||||||
|
|
||||||
|
Install from the [PostgreSQL Extension Network](https://pgxn.org/dist/vector) with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pgxn install vector
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hosted Postgres
|
||||||
|
|
||||||
|
Some Postgres providers only support specific extensions. To request a new extension:
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
### 0.1.1
|
### 0.1.1
|
||||||
|
|
||||||
Follow the [installation instructions](#installation) and run:
|
Compile and install the latest version and run:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER EXTENSION vector UPDATE TO '0.1.1';
|
ALTER EXTENSION vector UPDATE TO '0.1.1';
|
||||||
@@ -189,15 +235,9 @@ To run single tests:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
make installcheck REGRESS=vector # regression test
|
make installcheck REGRESS=vector # regression test
|
||||||
make prove_installcheck PROVE_TESTS=t/001_wal.pl # TAP test
|
make prove_installcheck PROVE_TESTS=test/t/001_wal.pl # TAP test
|
||||||
```
|
```
|
||||||
|
|
||||||
Directories
|
|
||||||
|
|
||||||
- `expected` - expected output for regression tests
|
|
||||||
- `sql` - regression tests
|
|
||||||
- `t` - TAP tests
|
|
||||||
|
|
||||||
Resources for contributors
|
Resources for contributors
|
||||||
|
|
||||||
- [Extension Building Infrastructure](https://www.postgresql.org/docs/current/extend-pgxs.html)
|
- [Extension Building Infrastructure](https://www.postgresql.org/docs/current/extend-pgxs.html)
|
||||||
|
|||||||
2
sql/vector--0.1.1--0.1.3.sql
Normal file
2
sql/vector--0.1.1--0.1.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.1.3'" to load this file. \quit
|
||||||
231
sql/vector.sql
231
sql/vector.sql
@@ -1,15 +1,218 @@
|
|||||||
SET client_min_messages = warning;
|
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
CREATE EXTENSION IF NOT EXISTS vector;
|
\echo Use "CREATE EXTENSION vector" to load this file. \quit
|
||||||
|
|
||||||
SELECT '[1,2,3]'::vector;
|
-- type
|
||||||
SELECT '[-1,2,3]'::vector;
|
|
||||||
SELECT '[hello,1]'::vector;
|
CREATE TYPE vector;
|
||||||
SELECT '[NaN,1]'::vector;
|
|
||||||
SELECT '[Infinity,1]'::vector;
|
CREATE FUNCTION vector_in(cstring, oid, integer) RETURNS vector
|
||||||
SELECT '[-Infinity,1]'::vector;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
SELECT '[1,2,3'::vector;
|
|
||||||
SELECT '[1,2,3]9'::vector;
|
CREATE FUNCTION vector_out(vector) RETURNS cstring
|
||||||
SELECT '1,2,3'::vector;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
SELECT '[]'::vector;
|
|
||||||
SELECT '[1,]'::vector;
|
CREATE FUNCTION vector_typmod_in(cstring[]) RETURNS integer
|
||||||
SELECT '[1,2,3]'::vector(2);
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_recv(internal, oid, integer) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_send(vector) RETURNS bytea
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE TYPE vector (
|
||||||
|
INPUT = vector_in,
|
||||||
|
OUTPUT = vector_out,
|
||||||
|
TYPMOD_IN = vector_typmod_in,
|
||||||
|
RECEIVE = vector_recv,
|
||||||
|
SEND = vector_send
|
||||||
|
);
|
||||||
|
|
||||||
|
-- functions
|
||||||
|
|
||||||
|
CREATE FUNCTION l2_distance(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION inner_product(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION cosine_distance(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_dims(vector) RETURNS integer
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_norm(vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_add(vector, vector) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_sub(vector, vector) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- private functions
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_lt(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_le(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_eq(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_ne(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_ge(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_gt(vector, vector) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_cmp(vector, vector) RETURNS int4
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_l2_squared_distance(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_negative_inner_product(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_spherical_distance(vector, vector) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- cast functions
|
||||||
|
|
||||||
|
CREATE FUNCTION vector(vector, integer, boolean) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION array_to_vector(integer[], integer, boolean) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION array_to_vector(real[], integer, boolean) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION array_to_vector(double precision[], integer, boolean) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- casts
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
-- operators
|
||||||
|
|
||||||
|
CREATE OPERATOR <-> (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = l2_distance,
|
||||||
|
COMMUTATOR = '<->'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <#> (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_negative_inner_product,
|
||||||
|
COMMUTATOR = '<#>'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <=> (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = cosine_distance,
|
||||||
|
COMMUTATOR = '<=>'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR + (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_add,
|
||||||
|
COMMUTATOR = +
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR - (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub,
|
||||||
|
COMMUTATOR = -
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR < (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_lt,
|
||||||
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
|
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
-- should use scalarlesel and scalarlejoinsel, but not supported in Postgres < 11
|
||||||
|
CREATE OPERATOR <= (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_le,
|
||||||
|
COMMUTATOR = >= , NEGATOR = > ,
|
||||||
|
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR = (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_eq,
|
||||||
|
COMMUTATOR = = , NEGATOR = <> ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <> (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ne,
|
||||||
|
COMMUTATOR = <> , NEGATOR = = ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
-- should use scalargesel and scalargejoinsel, but not supported in Postgres < 11
|
||||||
|
CREATE OPERATOR >= (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ge,
|
||||||
|
COMMUTATOR = <= , NEGATOR = < ,
|
||||||
|
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR > (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_gt,
|
||||||
|
COMMUTATOR = < , NEGATOR = <= ,
|
||||||
|
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
-- access method
|
||||||
|
|
||||||
|
CREATE FUNCTION ivfflathandler(internal) RETURNS index_am_handler
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||||
|
|
||||||
|
CREATE ACCESS METHOD ivfflat TYPE INDEX HANDLER ivfflathandler;
|
||||||
|
|
||||||
|
COMMENT ON ACCESS METHOD ivfflat IS 'ivfflat index access method';
|
||||||
|
|
||||||
|
-- opclasses
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS vector_ops
|
||||||
|
DEFAULT FOR TYPE vector USING btree AS
|
||||||
|
OPERATOR 1 < ,
|
||||||
|
OPERATOR 2 <= ,
|
||||||
|
OPERATOR 3 = ,
|
||||||
|
OPERATOR 4 >= ,
|
||||||
|
OPERATOR 5 > ,
|
||||||
|
FUNCTION 1 vector_cmp(vector, vector);
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS vector_l2_ops
|
||||||
|
DEFAULT FOR TYPE vector USING ivfflat AS
|
||||||
|
OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops,
|
||||||
|
FUNCTION 1 vector_l2_squared_distance(vector, vector),
|
||||||
|
FUNCTION 3 l2_distance(vector, vector);
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS vector_ip_ops
|
||||||
|
FOR TYPE vector USING ivfflat AS
|
||||||
|
OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops,
|
||||||
|
FUNCTION 1 vector_negative_inner_product(vector, vector),
|
||||||
|
FUNCTION 3 vector_spherical_distance(vector, vector),
|
||||||
|
FUNCTION 4 vector_norm(vector);
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS vector_cosine_ops
|
||||||
|
FOR TYPE vector USING ivfflat AS
|
||||||
|
OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops,
|
||||||
|
FUNCTION 1 vector_negative_inner_product(vector, vector),
|
||||||
|
FUNCTION 2 vector_norm(vector),
|
||||||
|
FUNCTION 3 vector_spherical_distance(vector, vector),
|
||||||
|
FUNCTION 4 vector_norm(vector);
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ _PG_init(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate the cost of an index scan
|
* Estimate the cost of an index scan
|
||||||
*
|
|
||||||
* TODO Improve cost estimation
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ivfflatcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
|
ivfflatcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
|
||||||
@@ -42,6 +40,9 @@ ivfflatcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
GenericCosts costs;
|
GenericCosts costs;
|
||||||
|
int lists;
|
||||||
|
double ratio;
|
||||||
|
Relation indexRel;
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 120000
|
#if PG_VERSION_NUM < 120000
|
||||||
List *qinfos;
|
List *qinfos;
|
||||||
@@ -57,7 +58,18 @@ ivfflatcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
|
|||||||
genericcostestimate(root, path, loop_count, qinfos, &costs);
|
genericcostestimate(root, path, loop_count, qinfos, &costs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*indexStartupCost = costs.indexStartupCost;
|
indexRel = index_open(path->indexinfo->indexoid, NoLock);
|
||||||
|
lists = IvfflatGetLists(indexRel);
|
||||||
|
index_close(indexRel, NoLock);
|
||||||
|
|
||||||
|
ratio = ((double) ivfflat_probes) / lists;
|
||||||
|
if (ratio > 1)
|
||||||
|
ratio = 1;
|
||||||
|
|
||||||
|
costs.indexTotalCost *= ratio;
|
||||||
|
|
||||||
|
/* Startup cost and total cost are same */
|
||||||
|
*indexStartupCost = costs.indexTotalCost;
|
||||||
*indexTotalCost = costs.indexTotalCost;
|
*indexTotalCost = costs.indexTotalCost;
|
||||||
*indexSelectivity = costs.indexSelectivity;
|
*indexSelectivity = costs.indexSelectivity;
|
||||||
*indexCorrelation = costs.indexCorrelation;
|
*indexCorrelation = costs.indexCorrelation;
|
||||||
|
|||||||
@@ -244,11 +244,10 @@ vector_recv(PG_FUNCTION_ARGS)
|
|||||||
int32 typmod = PG_GETARG_INT32(2);
|
int32 typmod = PG_GETARG_INT32(2);
|
||||||
Vector *result;
|
Vector *result;
|
||||||
int16 dim;
|
int16 dim;
|
||||||
int16 unused;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dim = pq_getmsgint(buf, sizeof(int16));
|
dim = pq_getmsgint(buf, sizeof(int16));
|
||||||
unused = pq_getmsgint(buf, sizeof(int16));
|
pq_getmsgint(buf, sizeof(int16)); /* unused */
|
||||||
|
|
||||||
CheckDim(dim);
|
CheckDim(dim);
|
||||||
CheckExpectedDim(typmod, dim);
|
CheckExpectedDim(typmod, dim);
|
||||||
|
|||||||
17
test/expected/ivfflat_options.out
Normal file
17
test/expected/ivfflat_options.out
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
SET client_min_messages = warning;
|
||||||
|
CREATE EXTENSION IF NOT EXISTS vector;
|
||||||
|
SET enable_seqscan = off;
|
||||||
|
CREATE TABLE t (val vector(3));
|
||||||
|
CREATE INDEX ON t USING ivfflat (val) WITH (lists = 0);
|
||||||
|
ERROR: value 0 out of bounds for option "lists"
|
||||||
|
DETAIL: Valid values are between "1" and "32768".
|
||||||
|
CREATE INDEX ON t USING ivfflat (val) WITH (lists = 32769);
|
||||||
|
ERROR: value 32769 out of bounds for option "lists"
|
||||||
|
DETAIL: Valid values are between "1" and "32768".
|
||||||
|
SHOW ivfflat.probes;
|
||||||
|
ivfflat.probes
|
||||||
|
----------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP TABLE t;
|
||||||
15
test/sql/input.sql
Normal file
15
test/sql/input.sql
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
SET client_min_messages = warning;
|
||||||
|
CREATE EXTENSION IF NOT EXISTS vector;
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::vector;
|
||||||
|
SELECT '[-1,2,3]'::vector;
|
||||||
|
SELECT '[hello,1]'::vector;
|
||||||
|
SELECT '[NaN,1]'::vector;
|
||||||
|
SELECT '[Infinity,1]'::vector;
|
||||||
|
SELECT '[-Infinity,1]'::vector;
|
||||||
|
SELECT '[1,2,3'::vector;
|
||||||
|
SELECT '[1,2,3]9'::vector;
|
||||||
|
SELECT '1,2,3'::vector;
|
||||||
|
SELECT '[]'::vector;
|
||||||
|
SELECT '[1,]'::vector;
|
||||||
|
SELECT '[1,2,3]'::vector(2);
|
||||||
@@ -21,8 +21,9 @@ sub test_index_replay
|
|||||||
my $caughtup_query;
|
my $caughtup_query;
|
||||||
my $server_version_num = $node_primary->safe_psql("postgres", "SHOW server_version_num");
|
my $server_version_num = $node_primary->safe_psql("postgres", "SHOW server_version_num");
|
||||||
if ($server_version_num >= 100000) {
|
if ($server_version_num >= 100000) {
|
||||||
$caughtup_query = "SELECT pg_current_wal_lsn() <= write_lsn FROM pg_stat_replication WHERE application_name = '$applname';";
|
$caughtup_query = "SELECT pg_current_wal_lsn() <= replay_lsn FROM pg_stat_replication WHERE application_name = '$applname';";
|
||||||
} else {
|
} else {
|
||||||
|
# TODO figure out why replay location doesn't work
|
||||||
$caughtup_query = "SELECT pg_current_xlog_location() <= write_location FROM pg_stat_replication WHERE application_name = '$applname';";
|
$caughtup_query = "SELECT pg_current_xlog_location() <= write_location FROM pg_stat_replication WHERE application_name = '$applname';";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
|
||||||
\echo Use "CREATE EXTENSION vector" to load this file. \quit
|
|
||||||
|
|
||||||
-- type
|
|
||||||
|
|
||||||
CREATE TYPE vector;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_in(cstring, oid, integer) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_out(vector) RETURNS cstring
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_typmod_in(cstring[]) RETURNS integer
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_recv(internal, oid, integer) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_send(vector) RETURNS bytea
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE TYPE vector (
|
|
||||||
INPUT = vector_in,
|
|
||||||
OUTPUT = vector_out,
|
|
||||||
TYPMOD_IN = vector_typmod_in,
|
|
||||||
RECEIVE = vector_recv,
|
|
||||||
SEND = vector_send
|
|
||||||
);
|
|
||||||
|
|
||||||
-- functions
|
|
||||||
|
|
||||||
CREATE FUNCTION l2_distance(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION inner_product(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION cosine_distance(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_dims(vector) RETURNS integer
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_norm(vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_add(vector, vector) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_sub(vector, vector) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
-- private functions
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_lt(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_le(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_eq(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_ne(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_ge(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_gt(vector, vector) RETURNS bool
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_cmp(vector, vector) RETURNS int4
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_l2_squared_distance(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_negative_inner_product(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION vector_spherical_distance(vector, vector) RETURNS float8
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
-- cast functions
|
|
||||||
|
|
||||||
CREATE FUNCTION vector(vector, integer, boolean) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION array_to_vector(integer[], integer, boolean) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION array_to_vector(real[], integer, boolean) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
CREATE FUNCTION array_to_vector(double precision[], integer, boolean) RETURNS vector
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
||||||
|
|
||||||
-- casts
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
-- operators
|
|
||||||
|
|
||||||
CREATE OPERATOR <-> (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = l2_distance,
|
|
||||||
COMMUTATOR = '<->'
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR <#> (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_negative_inner_product,
|
|
||||||
COMMUTATOR = '<#>'
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR <=> (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = cosine_distance,
|
|
||||||
COMMUTATOR = '<=>'
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR + (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_add,
|
|
||||||
COMMUTATOR = +
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR - (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub,
|
|
||||||
COMMUTATOR = -
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR < (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_lt,
|
|
||||||
COMMUTATOR = > , NEGATOR = >= ,
|
|
||||||
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
-- should use scalarlesel and scalarlejoinsel, but not supported in Postgres < 11
|
|
||||||
CREATE OPERATOR <= (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_le,
|
|
||||||
COMMUTATOR = >= , NEGATOR = > ,
|
|
||||||
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR = (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_eq,
|
|
||||||
COMMUTATOR = = , NEGATOR = <> ,
|
|
||||||
RESTRICT = eqsel, JOIN = eqjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR <> (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ne,
|
|
||||||
COMMUTATOR = <> , NEGATOR = = ,
|
|
||||||
RESTRICT = eqsel, JOIN = eqjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
-- should use scalargesel and scalargejoinsel, but not supported in Postgres < 11
|
|
||||||
CREATE OPERATOR >= (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ge,
|
|
||||||
COMMUTATOR = <= , NEGATOR = < ,
|
|
||||||
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OPERATOR > (
|
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_gt,
|
|
||||||
COMMUTATOR = < , NEGATOR = <= ,
|
|
||||||
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
|
||||||
);
|
|
||||||
|
|
||||||
-- access method
|
|
||||||
|
|
||||||
CREATE FUNCTION ivfflathandler(internal) RETURNS index_am_handler
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
|
||||||
|
|
||||||
CREATE ACCESS METHOD ivfflat TYPE INDEX HANDLER ivfflathandler;
|
|
||||||
|
|
||||||
COMMENT ON ACCESS METHOD ivfflat IS 'ivfflat index access method';
|
|
||||||
|
|
||||||
-- opclasses
|
|
||||||
|
|
||||||
CREATE OPERATOR CLASS vector_ops
|
|
||||||
DEFAULT FOR TYPE vector USING btree AS
|
|
||||||
OPERATOR 1 < ,
|
|
||||||
OPERATOR 2 <= ,
|
|
||||||
OPERATOR 3 = ,
|
|
||||||
OPERATOR 4 >= ,
|
|
||||||
OPERATOR 5 > ,
|
|
||||||
FUNCTION 1 vector_cmp(vector, vector);
|
|
||||||
|
|
||||||
CREATE OPERATOR CLASS vector_l2_ops
|
|
||||||
DEFAULT FOR TYPE vector USING ivfflat AS
|
|
||||||
OPERATOR 1 <-> (vector, vector) FOR ORDER BY float_ops,
|
|
||||||
FUNCTION 1 vector_l2_squared_distance(vector, vector),
|
|
||||||
FUNCTION 3 l2_distance(vector, vector);
|
|
||||||
|
|
||||||
CREATE OPERATOR CLASS vector_ip_ops
|
|
||||||
FOR TYPE vector USING ivfflat AS
|
|
||||||
OPERATOR 1 <#> (vector, vector) FOR ORDER BY float_ops,
|
|
||||||
FUNCTION 1 vector_negative_inner_product(vector, vector),
|
|
||||||
FUNCTION 3 vector_spherical_distance(vector, vector),
|
|
||||||
FUNCTION 4 vector_norm(vector);
|
|
||||||
|
|
||||||
CREATE OPERATOR CLASS vector_cosine_ops
|
|
||||||
FOR TYPE vector USING ivfflat AS
|
|
||||||
OPERATOR 1 <=> (vector, vector) FOR ORDER BY float_ops,
|
|
||||||
FUNCTION 1 vector_negative_inner_product(vector, vector),
|
|
||||||
FUNCTION 2 vector_norm(vector),
|
|
||||||
FUNCTION 3 vector_spherical_distance(vector, vector),
|
|
||||||
FUNCTION 4 vector_norm(vector);
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
comment = 'vector data type and ivfflat access method'
|
comment = 'vector data type and ivfflat access method'
|
||||||
default_version = '0.1.1'
|
default_version = '0.1.3'
|
||||||
module_pathname = '$libdir/vector'
|
module_pathname = '$libdir/vector'
|
||||||
relocatable = true
|
relocatable = true
|
||||||
|
|||||||
Reference in New Issue
Block a user