Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
```

Expand Down Expand Up @@ -97,47 +98,47 @@ 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.

### Example Queries

```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;

-- Nearest-neighbour search by L1 distance (full table scan)
-- 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
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;
Expand Down
127 changes: 127 additions & 0 deletions mysql-test/r/readme_examples.result
Original file line number Diff line number Diff line change
@@ -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;
107 changes: 107 additions & 0 deletions mysql-test/t/readme_examples.test
Original file line number Diff line number Diff line change
@@ -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;
Loading