Compare commits

...

8 Commits

Author SHA1 Message Date
Andrew Kane
f7a0abe6ad Added random_vector function 2023-01-26 18:41:46 -08:00
Andrew Kane
9b13db5c5c Updated link [skip ci] 2023-01-18 04:31:42 -08:00
Andrew Kane
ca9d4ed82a Updated readme [skip ci] 2023-01-13 10:30:34 -08:00
Andrew Kane
b1ffe2d4d3 Updated readme [skip ci] 2023-01-13 00:41:13 -08:00
Andrew Kane
246f8814bc Updated readme [skip ci] 2023-01-13 00:40:37 -08:00
Andrew Kane
a5d8bb2688 Added link to feedstock [skip ci] 2023-01-12 02:15:18 -08:00
Andrew Kane
95e496ba00 Added conda-forge to readme - closes #47 [skip ci] 2023-01-12 02:02:18 -08:00
Andrew Kane
6bfc2cb9a1 Use table for libraries [skip ci] 2023-01-11 14:34:33 -08:00
13 changed files with 81 additions and 46 deletions

View File

@@ -1,3 +1,7 @@
## 0.4.1 (unreleased)
- Added `random_vector` function
## 0.4.0 (2023-01-11)
If upgrading with Postgres < 13, see [this note](https://github.com/pgvector/pgvector#040).

View File

@@ -29,7 +29,7 @@ Then load it in databases where you want to use it
CREATE EXTENSION vector;
```
You can also install it with [Docker](#docker), [Homebrew](#homebrew), or [PGXN](#pgxn)
You can also install it with [Docker](#docker), [Homebrew](#homebrew), [PGXN](#pgxn), or [conda-forge](#conda-forge)
## Getting Started
@@ -184,26 +184,26 @@ inner_product(vector, vector) → double precision | inner product
l2_distance(vector, vector) → double precision | Euclidean distance
vector_dims(vector) → integer | number of dimensions
vector_norm(vector) → double precision | Euclidean norm
random_vector(integer) → vector | random vector [unreleased]
### Aggregate Functions
Function | Description | Partial Mode
--- | --- | ---
avg(vector) → vector | arithmetic mean | Yes
Function | Description
--- | ---
avg(vector) → vector | arithmetic mean
## Libraries
Libraries that use pgvector:
- [pgvector-python](https://github.com/pgvector/pgvector-python) (Python)
- [Neighbor](https://github.com/ankane/neighbor) (Ruby)
- [pgvector-ruby](https://github.com/pgvector/pgvector-ruby) (Ruby)
- [pgvector-node](https://github.com/pgvector/pgvector-node) (Node.js)
- [pgvector-go](https://github.com/pgvector/pgvector-go) (Go)
- [pgvector-php](https://github.com/pgvector/pgvector-php) (PHP)
- [pgvector-rust](https://github.com/pgvector/pgvector-rust) (Rust)
- [pgvector-cpp](https://github.com/pgvector/pgvector-cpp) (C++)
- [pgvector-elixir](https://github.com/pgvector/pgvector-elixir) (Elixir)
Language | Libraries
--- | ---
Python | [pgvector-python](https://github.com/pgvector/pgvector-python)
Ruby | [Neighbor](https://github.com/ankane/neighbor), [pgvector-ruby](https://github.com/pgvector/pgvector-ruby)
Node | [pgvector-node](https://github.com/pgvector/pgvector-node)
Go | [pgvector-go](https://github.com/pgvector/pgvector-go)
PHP | [pgvector-php](https://github.com/pgvector/pgvector-php)
Rust | [pgvector-rust](https://github.com/pgvector/pgvector-rust)
C++ | [pgvector-cpp](https://github.com/pgvector/pgvector-cpp)
Elixir | [pgvector-elixir](https://github.com/pgvector/pgvector-elixir)
## Frequently Asked Questions
@@ -258,12 +258,22 @@ Install from the [PostgreSQL Extension Network](https://pgxn.org/dist/vector) wi
pgxn install vector
```
### conda-forge
Install from [conda-forge](https://anaconda.org/conda-forge/pgvector) with:
```sh
conda install -c conda-forge pgvector
```
This method is [community-maintained](https://github.com/conda-forge/pgvector-feedstock) by [@mmcauliffe](https://github.com/mmcauliffe)
## 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)
- Google Cloud SQL - vote or comment on [this page](https://issuetracker.google.com/issues/265172065)
- 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 - vote or comment on [this page](https://feedback.azure.com/d365community/idea/7b423322-6189-ed11-a81b-000d3ae49307)
@@ -279,7 +289,7 @@ ALTER EXTENSION vector UPDATE;
### 0.4.0
For Postgres < 13, remove this line from `sql/vector--0.3.2--0.4.0.sql`:
If upgrading with Postgres < 13, remove this line from `sql/vector--0.3.2--0.4.0.sql`:
```sql
ALTER TYPE vector SET (STORAGE = extended);

View File

@@ -0,0 +1,5 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION vector UPDATE TO '0.4.1'" to load this file. \quit
CREATE FUNCTION random_vector(integer) RETURNS vector
AS 'MODULE_PATHNAME' LANGUAGE C VOLATILE STRICT PARALLEL SAFE;

View File

@@ -52,6 +52,9 @@ CREATE FUNCTION vector_add(vector, vector) RETURNS vector
CREATE FUNCTION vector_sub(vector, vector) RETURNS vector
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION random_vector(integer) RETURNS vector
AS 'MODULE_PATHNAME' LANGUAGE C VOLATILE STRICT PARALLEL SAFE;
-- private functions
CREATE FUNCTION vector_lt(vector, vector) RETURNS bool

View File

@@ -10,15 +10,10 @@
#include "access/generic_xlog.h"
#include "access/reloptions.h"
#include "nodes/execnodes.h"
#include "port.h" /* for strtof() and random() */
#include "utils/sampling.h"
#include "utils/tuplesort.h"
#include "vector.h"
#if PG_VERSION_NUM >= 150000
#include "common/pg_prng.h"
#endif
#ifdef IVFFLAT_BENCH
#include "portability/instr_time.h"
#endif
@@ -68,14 +63,6 @@
#define IvfflatBench(name, code) (code)
#endif
#if PG_VERSION_NUM >= 150000
#define RandomDouble() pg_prng_double(&pg_global_prng_state)
#define RandomInt() pg_prng_uint32(&pg_global_prng_state)
#else
#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE)
#define RandomInt() random()
#endif
/* Variables */
extern int ivfflat_probes;

View File

@@ -950,3 +950,22 @@ vector_avg(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(result);
}
/*
* Generate a random vector
*/
PGDLLEXPORT PG_FUNCTION_INFO_V1(random_vector);
Datum
random_vector(PG_FUNCTION_ARGS)
{
int32 dim = PG_GETARG_INT32(0);
Vector *result;
CheckDim(dim);
result = InitVector(dim);
for (int i = 0; i < dim; i++)
result->x[i] = RandomDouble();
PG_RETURN_POINTER(result);
}

View File

@@ -3,6 +3,12 @@
#include "postgres.h"
#include "port.h" /* for strtof() and random() */
#if PG_VERSION_NUM >= 150000
#include "common/pg_prng.h"
#endif
#define VECTOR_MAX_DIM 16000
#define VECTOR_SIZE(_dim) (offsetof(Vector, x) + sizeof(float)*(_dim))
@@ -10,6 +16,14 @@
#define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x))
#define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x)
#if PG_VERSION_NUM >= 150000
#define RandomDouble() pg_prng_double(&pg_global_prng_state)
#define RandomInt() pg_prng_uint32(&pg_global_prng_state)
#else
#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE)
#define RandomInt() random()
#endif
typedef struct Vector
{
int32 vl_len_; /* varlena header (do not touch directly!) */

View File

@@ -44,11 +44,6 @@ sub test_index_replay
return;
}
# Use ARRAY[random(), random(), random(), ...] over
# SELECT array_agg(random()) FROM generate_series(1, $dim)
# to generate different values for each row
my $array_sql = join(",", ('random()') x $dim);
# Initialize primary node
$node_primary = get_new_node('primary');
$node_primary->init(allows_streaming => 1);
@@ -75,7 +70,7 @@ $node_replica->start;
$node_primary->safe_psql("postgres", "CREATE EXTENSION vector;");
$node_primary->safe_psql("postgres", "CREATE TABLE tst (i int4, v vector($dim));");
$node_primary->safe_psql("postgres",
"INSERT INTO tst SELECT i % 10, ARRAY[$array_sql] FROM generate_series(1, 100000) i;"
"INSERT INTO tst SELECT i % 10, random_vector($dim) FROM generate_series(1, 100000) i;"
);
$node_primary->safe_psql("postgres", "CREATE INDEX ON tst USING ivfflat (v);");
@@ -91,7 +86,7 @@ for my $i (1 .. 10)
test_index_replay("vacuum $i");
my ($start, $end) = (100001 + ($i - 1) * 10000, 100000 + $i * 10000);
$node_primary->safe_psql("postgres",
"INSERT INTO tst SELECT i % 10, ARRAY[$array_sql] FROM generate_series($start, $end) i;"
"INSERT INTO tst SELECT i % 10, random_vector($dim) FROM generate_series($start, $end) i;"
);
test_index_replay("insert $i");
}

View File

@@ -46,7 +46,7 @@ $node->start;
$node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (i int4, v vector(3));");
$node->safe_psql("postgres",
"INSERT INTO tst SELECT i, ARRAY[random(), random(), random()] FROM generate_series(1, 100000) i;"
"INSERT INTO tst SELECT i, random_vector(3) FROM generate_series(1, 100000) i;"
);
# Generate queries

View File

@@ -13,7 +13,7 @@ $node->start;
$node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (i int4 primary key, v vector(3));");
$node->safe_psql("postgres",
"INSERT INTO tst SELECT i, ARRAY[random(), random(), random()] FROM generate_series(1, 100000) i;"
"INSERT INTO tst SELECT i, random_vector(3) FROM generate_series(1, 100000) i;"
);
# Check each index type

View File

@@ -13,7 +13,7 @@ $node->start;
$node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (v vector(3));");
$node->safe_psql("postgres",
"INSERT INTO tst SELECT ARRAY[random(), random(), random()] FROM generate_series(1, 100000) i;"
"INSERT INTO tst SELECT random_vector(3) FROM generate_series(1, 100000) i;"
);
$node->safe_psql("postgres", "CREATE INDEX lists50 ON tst USING ivfflat (v) WITH (lists = 50);");

View File

@@ -6,8 +6,6 @@ use Test::More tests => 5;
my $dim = 768;
my $array_sql = join(",", ('random()') x $dim);
# Initialize node
my $node = get_new_node('node');
$node->init;
@@ -17,7 +15,7 @@ $node->start;
$node->safe_psql("postgres", "CREATE EXTENSION vector;");
$node->safe_psql("postgres", "CREATE TABLE tst (v vector($dim));");
$node->safe_psql("postgres",
"INSERT INTO tst SELECT ARRAY[$array_sql] FROM generate_series(1, 10000) i;"
"INSERT INTO tst SELECT random_vector($dim) FROM generate_series(1, 10000) i;"
);
$node->safe_psql("postgres", "CREATE INDEX ON tst USING ivfflat (v);");
@@ -28,7 +26,7 @@ $node->pgbench(
[qr{^$}],
"concurrent INSERTs",
{
"007_inserts" => "INSERT INTO tst SELECT ARRAY[$array_sql] FROM generate_series(1, 10) i;"
"007_inserts" => "INSERT INTO tst SELECT random_vector($dim) FROM generate_series(1, 10) i;"
}
);

View File

@@ -17,7 +17,7 @@ $node->safe_psql("postgres", "CREATE TABLE tst (v1 vector(1024), v2 vector(1024)
# Test insert succeeds
$node->safe_psql("postgres",
"INSERT INTO tst SELECT array_agg(n), array_agg(n), array_agg(n) FROM generate_series(1, $dim) n"
"INSERT INTO tst SELECT random_vector($dim), random_vector($dim), random_vector($dim)"
);
# Change storage to PLAIN
@@ -27,6 +27,6 @@ $node->safe_psql("postgres", "ALTER TABLE tst ALTER COLUMN v3 SET STORAGE PLAIN"
# Test insert fails
my ($ret, $stdout, $stderr) = $node->psql("postgres",
"INSERT INTO tst SELECT array_agg(n), array_agg(n), array_agg(n) FROM generate_series(1, $dim) n"
"INSERT INTO tst SELECT random_vector($dim), random_vector($dim), random_vector($dim)"
);
like($stderr, qr/row is too big/);