diff --git a/README.md b/README.md index 83ccc25..63bf351 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,10 @@ An extension for VillageSQL Server that adds a vector data type with external co ### Loading the Extension -Before using any SVECTOR features, load the extension in your session: +Because this extension depends on preview APIs, you must enable preview extensions before installing: ```sql +SET PERSIST vsql_allow_preview_extensions = ON; INSTALL EXTENSION vsql_vector; ``` @@ -97,20 +98,20 @@ INSERT INTO embeddings VALUES (5, '[9.0, 8.0, 7.0, 6.0]', NULL); -- L1 dist fro | Function | Returns | Description | |---|---|---| -| `SVECTOR_DIMENSION(v)` | INT | Declared dimension of the vector | -| `SVECTOR_MAX_DIMENSION()` | INT | Maximum supported dimension (3072) | -| `SVECTOR_NORM(v)` | REAL | L2 (Euclidean) norm | -| `SVECTOR_FORMAT(v, precision)` | STRING | Vector as a fixed-precision decimal string | -| `SVECTOR_HEX(v)` | STRING | Raw float bytes as uppercase hex (useful for debugging) | +| `VECTOR_DIMENSION(v)` | INT | Declared dimension of the vector | +| `VECTOR_MAX_DIMENSION()` | INT | Maximum supported dimension (3072) | +| `VECTOR_NORM(v)` | REAL | L2 (Euclidean) norm | +| `VECTOR_FORMAT(v, precision)` | STRING | Vector as a fixed-precision decimal string | +| `VECTOR_HEX(v)` | STRING | Raw float bytes as uppercase hex (useful for debugging) | #### Distance and similarity functions | Function | Returns | Description | |---|---|---| -| `SVECTOR_DISTANCE_L1(v1, v2)` | REAL | L1 (Manhattan) distance — sum of absolute differences | -| `SVECTOR_DISTANCE_L2(v1, v2)` | REAL | L2 (Euclidean) distance — square root of sum of squared differences | -| `SVECTOR_DISTANCE_COSINE(v1, v2)` | REAL | Cosine distance — `1 - cosine_similarity`; range [0, 2] | -| `SVECTOR_INNER_PRODUCT(v1, v2)` | REAL | Dot product (similarity, not a metric); higher means more similar | +| `L1_DISTANCE(v1, v2)` | REAL | L1 (Manhattan) distance — sum of absolute differences | +| `L2_DISTANCE(v1, v2)` | REAL | L2 (Euclidean) distance — square root of sum of squared differences | +| `COSINE_DISTANCE(v1, v2)` | REAL | Cosine distance — `1 - cosine_similarity`; range [0, 2] | +| `INNER_PRODUCT(v1, v2)` | REAL | Dot product (similarity, not a metric); higher means more similar | Both arguments to a distance/similarity function must have the same dimension. All functions return NULL if either argument is NULL. @@ -118,10 +119,10 @@ Both arguments to a distance/similarity function must have the same dimension. A ```sql -- Norm of a stored vector -SELECT id, SVECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; +SELECT id, VECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; -- L2 distance between two stored vectors -SELECT SVECTOR_DISTANCE_L2(a.vec, b.vec) AS dist +SELECT L2_DISTANCE(a.vec, b.vec) AS dist FROM embeddings a, embeddings b WHERE a.id = 1 AND b.id = 2; @@ -129,7 +130,7 @@ WHERE a.id = 1 AND b.id = 2; -- Note: HNSW index support is planned; today this performs a sequential scan. -- The query vector is stored in a table row and joined in as a workaround -- for the current limitation on inline constant vectors (see Known Limitations). -SELECT id, SVECTOR_DISTANCE_L1(vec, query.ref_vec) AS dist +SELECT id, L1_DISTANCE(vec, query.ref_vec) AS dist FROM embeddings, (SELECT vec AS ref_vec FROM embeddings WHERE id = 1) AS query ORDER BY dist ASC @@ -137,7 +138,7 @@ LIMIT 2; -- Expected result: id=1 dist=0, id=2 dist=1 -- TODO: once inline constant vector support is added, the intended syntax is: --- SELECT id, SVECTOR_DISTANCE_L1(vec, '[1.0, 2.0, 3.0, 4.0]') AS dist +-- SELECT id, L1_DISTANCE(vec, '[1.0, 2.0, 3.0, 4.0]') AS dist -- FROM embeddings -- ORDER BY dist ASC -- LIMIT 2; diff --git a/mysql-test/r/readme_examples.result b/mysql-test/r/readme_examples.result new file mode 100644 index 0000000..dd5f69c --- /dev/null +++ b/mysql-test/r/readme_examples.result @@ -0,0 +1,127 @@ +SET PERSIST vsql_allow_preview_extensions = ON; +INSTALL EXTENSION vsql_vector; +# ---- README: SVECTOR Type ---- +# Create a table with a vector column +CREATE TABLE embeddings ( +id INT PRIMARY KEY, +vec SVECTOR(4) NOT NULL +) ENGINE=InnoDB; +# Add a vector column to an existing table +ALTER TABLE embeddings ADD COLUMN vec2 SVECTOR(4) NULL; +# Insert vectors (number of elements must match the declared dimension) +INSERT INTO embeddings VALUES (1, '[1.0, 2.0, 3.0, 4.0]', NULL); +INSERT INTO embeddings VALUES (2, '[1.0, 2.0, 3.0, 5.0]', NULL); +INSERT INTO embeddings VALUES (3, '[1.0, 2.0, 5.0, 4.0]', NULL); +INSERT INTO embeddings VALUES (4, '[2.0, 4.0, 6.0, 8.0]', NULL); +INSERT INTO embeddings VALUES (5, '[9.0, 8.0, 7.0, 6.0]', NULL); +# ---- README: Scalar / utility functions ---- +SELECT VECTOR_MAX_DIMENSION() AS max_dim; +max_dim +3072 +SELECT id, VECTOR_DIMENSION(vec) AS dims FROM embeddings ORDER BY id; +id dims +1 4 +2 4 +3 4 +4 4 +5 4 +SELECT id, VECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; +id norm +1 5.477225575051661 +2 6.244997998398398 +3 6.782329983125268 +4 10.954451150103322 +5 15.165750888103101 +SELECT id, VECTOR_FORMAT(vec, 2) AS formatted FROM embeddings ORDER BY id; +id formatted +1 [1,2,3,4] +2 [1,2,3,5] +3 [1,2,5,4] +4 [2,4,6,8] +5 [9,8,7,6] +SELECT SUBSTRING(VECTOR_HEX(vec), 17) AS hex_data FROM embeddings WHERE id = 1; +hex_data +0000803F000000400000404000008040 +# ---- README: Distance and similarity functions ---- +CREATE TABLE func_exact ( +id INT PRIMARY KEY, +v1 SVECTOR(4) NOT NULL, +v2 SVECTOR(4) NOT NULL +) ENGINE=InnoDB; +INSERT INTO func_exact VALUES +(1, '[1.0, 0.0, 0.0, 0.0]', '[1.0, 0.0, 0.0, 0.0]'), +(2, '[1.0, 0.0, 0.0, 0.0]', '[0.0, 1.0, 0.0, 0.0]'); +# L1_DISTANCE +SELECT id, L1_DISTANCE(v1, v2) AS l1 FROM func_exact ORDER BY id; +id l1 +1 0 +2 2 +# L2_DISTANCE +SELECT id, L2_DISTANCE(v1, v2) AS l2 FROM func_exact ORDER BY id; +id l2 +1 0 +2 1.4142135623730951 +# COSINE_DISTANCE (0 = same direction, 1 = orthogonal) +SELECT id, COSINE_DISTANCE(v1, v2) AS cos_dist FROM func_exact ORDER BY id; +id cos_dist +1 0 +2 1 +# INNER_PRODUCT +SELECT id, INNER_PRODUCT(v1, v2) AS ip FROM func_exact ORDER BY id; +id ip +1 1 +2 0 +# NULL handling: distance functions return NULL when either argument is NULL +SELECT id, +L1_DISTANCE(vec, vec2) AS l1, +L2_DISTANCE(vec, vec2) AS l2, +COSINE_DISTANCE(vec, vec2) AS cos_dist, +INNER_PRODUCT(vec, vec2) AS ip +FROM embeddings ORDER BY id; +id l1 l2 cos_dist ip +1 NULL NULL NULL NULL +2 NULL NULL NULL NULL +3 NULL NULL NULL NULL +4 NULL NULL NULL NULL +5 NULL NULL NULL NULL +DROP TABLE func_exact; +# ---- README: Example Queries ---- +# Norm of a stored vector +SELECT id, VECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; +id norm +1 5.477225575051661 +2 6.244997998398398 +3 6.782329983125268 +4 10.954451150103322 +5 15.165750888103101 +# L2 distance between two stored vectors +SELECT L2_DISTANCE(a.vec, b.vec) AS dist +FROM embeddings a, embeddings b +WHERE a.id = 1 AND b.id = 2; +dist +1 +# Nearest-neighbour search by L1 distance (full table scan) +SELECT id, L1_DISTANCE(vec, query.ref_vec) AS dist +FROM embeddings, +(SELECT vec AS ref_vec FROM embeddings WHERE id = 1) AS query +ORDER BY dist ASC +LIMIT 2; +id dist +1 0 +2 1 +# Update a vector value +UPDATE embeddings SET vec = '[0.5, 0.5, 0.5, 0.5]' WHERE id = 1; +# Delete a row containing a vector +DELETE FROM embeddings WHERE id = 2; +# Verify state after update and delete +SELECT id, VECTOR_FORMAT(vec, 2) AS vec FROM embeddings ORDER BY id; +id vec +1 [0.5,0.5,0.5,0.5] +3 [1,2,5,4] +4 [2,4,6,8] +5 [9,8,7,6] +# Clean up +DROP TABLE embeddings; +UNINSTALL EXTENSION vsql_vector; +SET PERSIST vsql_allow_preview_extensions = OFF; +RESET PERSIST vsql_allow_preview_extensions; diff --git a/mysql-test/t/readme_examples.test b/mysql-test/t/readme_examples.test new file mode 100644 index 0000000..ec6bb1b --- /dev/null +++ b/mysql-test/t/readme_examples.test @@ -0,0 +1,107 @@ +# Install vsql-vector extension +SET PERSIST vsql_allow_preview_extensions = ON; +INSTALL EXTENSION vsql_vector; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR + +######################################################################## +# +# Verify all SQL syntaxes mentioned in README.md +# +######################################################################## + +--echo # ---- README: SVECTOR Type ---- + +--echo # Create a table with a vector column +CREATE TABLE embeddings ( + id INT PRIMARY KEY, + vec SVECTOR(4) NOT NULL +) ENGINE=InnoDB; + +--echo # Add a vector column to an existing table +ALTER TABLE embeddings ADD COLUMN vec2 SVECTOR(4) NULL; + +--echo # Insert vectors (number of elements must match the declared dimension) +INSERT INTO embeddings VALUES (1, '[1.0, 2.0, 3.0, 4.0]', NULL); +INSERT INTO embeddings VALUES (2, '[1.0, 2.0, 3.0, 5.0]', NULL); +INSERT INTO embeddings VALUES (3, '[1.0, 2.0, 5.0, 4.0]', NULL); +INSERT INTO embeddings VALUES (4, '[2.0, 4.0, 6.0, 8.0]', NULL); +INSERT INTO embeddings VALUES (5, '[9.0, 8.0, 7.0, 6.0]', NULL); + +--echo # ---- README: Scalar / utility functions ---- + +SELECT VECTOR_MAX_DIMENSION() AS max_dim; +SELECT id, VECTOR_DIMENSION(vec) AS dims FROM embeddings ORDER BY id; +SELECT id, VECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; +SELECT id, VECTOR_FORMAT(vec, 2) AS formatted FROM embeddings ORDER BY id; +SELECT SUBSTRING(VECTOR_HEX(vec), 17) AS hex_data FROM embeddings WHERE id = 1; + +--echo # ---- README: Distance and similarity functions ---- + +# Use unit-component vectors so sqrt() denominators are exact integers, +# giving fully deterministic results across all IEEE 754 platforms. +CREATE TABLE func_exact ( + id INT PRIMARY KEY, + v1 SVECTOR(4) NOT NULL, + v2 SVECTOR(4) NOT NULL +) ENGINE=InnoDB; + +INSERT INTO func_exact VALUES + (1, '[1.0, 0.0, 0.0, 0.0]', '[1.0, 0.0, 0.0, 0.0]'), + (2, '[1.0, 0.0, 0.0, 0.0]', '[0.0, 1.0, 0.0, 0.0]'); + +--echo # L1_DISTANCE +SELECT id, L1_DISTANCE(v1, v2) AS l1 FROM func_exact ORDER BY id; + +--echo # L2_DISTANCE +SELECT id, L2_DISTANCE(v1, v2) AS l2 FROM func_exact ORDER BY id; + +--echo # COSINE_DISTANCE (0 = same direction, 1 = orthogonal) +SELECT id, COSINE_DISTANCE(v1, v2) AS cos_dist FROM func_exact ORDER BY id; + +--echo # INNER_PRODUCT +SELECT id, INNER_PRODUCT(v1, v2) AS ip FROM func_exact ORDER BY id; + +--echo # NULL handling: distance functions return NULL when either argument is NULL +SELECT id, + L1_DISTANCE(vec, vec2) AS l1, + L2_DISTANCE(vec, vec2) AS l2, + COSINE_DISTANCE(vec, vec2) AS cos_dist, + INNER_PRODUCT(vec, vec2) AS ip +FROM embeddings ORDER BY id; + +DROP TABLE func_exact; + +--echo # ---- README: Example Queries ---- + +--echo # Norm of a stored vector +SELECT id, VECTOR_NORM(vec) AS norm FROM embeddings ORDER BY id; + +--echo # L2 distance between two stored vectors +SELECT L2_DISTANCE(a.vec, b.vec) AS dist +FROM embeddings a, embeddings b +WHERE a.id = 1 AND b.id = 2; + +--echo # Nearest-neighbour search by L1 distance (full table scan) +SELECT id, L1_DISTANCE(vec, query.ref_vec) AS dist +FROM embeddings, + (SELECT vec AS ref_vec FROM embeddings WHERE id = 1) AS query +ORDER BY dist ASC +LIMIT 2; + +--echo # Update a vector value +UPDATE embeddings SET vec = '[0.5, 0.5, 0.5, 0.5]' WHERE id = 1; + +--echo # Delete a row containing a vector +DELETE FROM embeddings WHERE id = 2; + +--echo # Verify state after update and delete +SELECT id, VECTOR_FORMAT(vec, 2) AS vec FROM embeddings ORDER BY id; + +--echo # Clean up +DROP TABLE embeddings; + +UNINSTALL EXTENSION vsql_vector; +SET PERSIST vsql_allow_preview_extensions = OFF; +RESET PERSIST vsql_allow_preview_extensions;