[13.x] Fix MariaDB vector distance SQL and add AsVector Eloquent cast - #61337
Merged
Conversation
MariaDB's VEC_DISTANCE_* functions only accept VECTOR arguments, so the
JSON text bound by the vector query builder methods must be converted
with vec_fromtext(). Without it every whereVectorSimilarTo /
whereVectorDistanceLessThan / orderByVectorDistance / selectVectorDistance
call fails on MariaDB with "4079 Illegal parameter data type varchar for
operation 'VEC_DISTANCE_COSINE'".
Adds an AsVector cast so Eloquent models can read and write vector
columns: it decodes MariaDB's little-endian float32 bytes as well as
pgvector / vec_totext() JSON text, and writes vec_fromtext('[...]') on
MariaDB (which rejects text or raw bytes bound to a VECTOR column) or a
plain JSON string elsewhere.
eas4ai
force-pushed
the
mariadb-vector-cast
branch
from
August 25, 2026 17:55
7be4082 to
1b45538
Compare
Contributor
Author
|
Waiting on #61335 merge to fix CI failures not related to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #61250, which routed the vector query builder methods through the grammar and added MariaDB support via
vec_distance_cosine().1. Bug fix: the MariaDB SQL from #61250 is rejected by the server
MariaDB's
VEC_DISTANCE_*functions only acceptVECTORarguments. The query builder binds the vector as JSON text, sovec_distance_cosine(col, ?)fails on a real server for everywhereVectorSimilarTo/whereVectorDistanceLessThan/orderByVectorDistance/selectVectorDistancecall (reproduced on MariaDB 11.8.9, with both native and emulated prepares):MariaDbGrammar::compileVectorDistanceExpression()now emitsvec_distance_cosine(col, vec_fromtext(?)). The bindings are unchanged (still JSON text), andEXPLAINconfirms the MHNSWVECTOR INDEXis still used fororder by vec_distance_cosine(..., vec_fromtext(?)).2. New
AsVectorEloquent castVector columns had no first-party cast. On MariaDB the
arraycast cannot work at all: the column is returned as little-endian float32 bytes, and a JSON string bound to aVECTORcolumn is rejected with1292 Incorrect vector value(raw packed bytes bound as a parameter are rejected too, regardless ofPDO::PARAM_LOB).Illuminate\Database\Eloquent\Casts\AsVectoris driver-portable:unpack('g*')), pgvector /vec_totext()JSON text, and a not-yet-persisted MariaDB value (so$model->embeddingworks right aftercreate()).arrayorArrayable(e.g. aCollection) of floats. On MariaDB it stores avec_fromtext('[...]')expression, since the conversion has to happen server-side; on other drivers it stores the JSON string (which pgvector accepts). The inlined JSON only ever contains digits,.,-,e,,and brackets (json_encode(..., JSON_THROW_ON_ERROR)rejects NaN/Inf), so it is safe to inline.Test plan
tests/Database/DatabaseQueryBuilderTest.php— MariaDB vector assertions updated tovec_fromtext(?).tests/Database/DatabaseEloquentAsVectorCastTest.php— new unit tests for the cast against the MariaDB and Postgres grammars (binary/text decoding,vec_fromtextvs JSON storage,Arrayableinput, null handling, invalid input, read-back before save).tests/Integration/Database/MariaDb/EloquentVectorTest.php— new end-to-end test (vector()+vectorIndex()migration, create/read/update through the cast,selectVectorDistance+whereVectorSimilarTo). Gated with#[RequiresDatabase('mariadb', '>=11.7.0')]since CI runsmariadb:10; passes locally against MariaDB 11.8.9.vendor/bin/phpunit tests/Database(2842 tests)vendor/bin/pint --test