diff --git a/CHANGELOG.md b/CHANGELOG.md index 46298ab..3604076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.1 (unreleased) + +- Fixed error with `ANALYZE` and vectors with different dimensions + ## 0.6.0 (2024-01-29) If upgrading with Postgres 12 or Docker, see [these notes](https://github.com/pgvector/pgvector#060). diff --git a/src/vector.c b/src/vector.c index 982b176..5f3cbbb 100644 --- a/src/vector.c +++ b/src/vector.c @@ -866,9 +866,10 @@ vector_mul(PG_FUNCTION_ARGS) int vector_cmp_internal(Vector * a, Vector * b) { - CheckDims(a, b); + int dim = Min(a->dim, b->dim); - for (int i = 0; i < a->dim; i++) + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < dim; i++) { if (a->x[i] < b->x[i]) return -1; @@ -876,6 +877,13 @@ vector_cmp_internal(Vector * a, Vector * b) if (a->x[i] > b->x[i]) return 1; } + + if (a->dim < b->dim) + return -1; + + if (a->dim > b->dim) + return 1; + return 0; } @@ -889,6 +897,9 @@ vector_lt(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) < 0); } @@ -902,6 +913,9 @@ vector_le(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) <= 0); } @@ -915,6 +929,9 @@ vector_eq(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) == 0); } @@ -928,6 +945,9 @@ vector_ne(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) != 0); } @@ -941,6 +961,9 @@ vector_ge(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) >= 0); } @@ -954,6 +977,9 @@ vector_gt(PG_FUNCTION_ARGS) Vector *a = PG_GETARG_VECTOR_P(0); Vector *b = PG_GETARG_VECTOR_P(1); + /* TODO Remove in 0.7.0 */ + CheckDims(a, b); + PG_RETURN_BOOL(vector_cmp_internal(a, b) > 0); } diff --git a/test/expected/functions.out b/test/expected/functions.out index 2840688..85d1a2f 100644 --- a/test/expected/functions.out +++ b/test/expected/functions.out @@ -24,6 +24,56 @@ SELECT '[1e37]'::vector * '[1e37]'; ERROR: value out of range: overflow SELECT '[1e-37]'::vector * '[1e-37]'; ERROR: value out of range: underflow +SELECT '[1,2,3]'::vector = '[1,2,3]'; + ?column? +---------- + t +(1 row) + +SELECT '[1,2,3]'::vector = '[1,2]'; +ERROR: different vector dimensions 3 and 2 +SELECT vector_cmp('[1,2,3]', '[1,2,3]'); + vector_cmp +------------ + 0 +(1 row) + +SELECT vector_cmp('[1,2,3]', '[0,0,0]'); + vector_cmp +------------ + 1 +(1 row) + +SELECT vector_cmp('[0,0,0]', '[1,2,3]'); + vector_cmp +------------ + -1 +(1 row) + +SELECT vector_cmp('[1,2]', '[1,2,3]'); + vector_cmp +------------ + -1 +(1 row) + +SELECT vector_cmp('[1,2,3]', '[1,2]'); + vector_cmp +------------ + 1 +(1 row) + +SELECT vector_cmp('[1,2]', '[2,3,4]'); + vector_cmp +------------ + -1 +(1 row) + +SELECT vector_cmp('[2,3]', '[1,2,3]'); + vector_cmp +------------ + 1 +(1 row) + SELECT vector_dims('[1,2,3]'); vector_dims ------------- diff --git a/test/sql/functions.sql b/test/sql/functions.sql index 914df36..6235684 100644 --- a/test/sql/functions.sql +++ b/test/sql/functions.sql @@ -6,6 +6,17 @@ SELECT '[1,2,3]'::vector * '[4,5,6]'; SELECT '[1e37]'::vector * '[1e37]'; SELECT '[1e-37]'::vector * '[1e-37]'; +SELECT '[1,2,3]'::vector = '[1,2,3]'; +SELECT '[1,2,3]'::vector = '[1,2]'; + +SELECT vector_cmp('[1,2,3]', '[1,2,3]'); +SELECT vector_cmp('[1,2,3]', '[0,0,0]'); +SELECT vector_cmp('[0,0,0]', '[1,2,3]'); +SELECT vector_cmp('[1,2]', '[1,2,3]'); +SELECT vector_cmp('[1,2,3]', '[1,2]'); +SELECT vector_cmp('[1,2]', '[2,3,4]'); +SELECT vector_cmp('[2,3]', '[1,2,3]'); + SELECT vector_dims('[1,2,3]'); SELECT round(vector_norm('[1,1]')::numeric, 5);