joelpaulkoch

joelpaulkoch

I have a custom Ecto type and want to call a SQL function when dumping a value of this type into a virtual table with SQLite.

I’m developing this library to use sqlite-vec with Elixir.

There are 3 vector types in sqlite-vec: float32, int8, and bit.
The most performant way to use sqlite-vec is to create a virtual table.
Then you can create vectors with SQL functions as constructors.

So, in SQL that would be something like this:

CREATE VIRTUAL TABLE vt USING vec0(id INTEGER PRIMARY KEY, embedding int8[2])

INSERT INTO vt(id, embedding) VALUES(1, vec_int8('[1, 2]'))

I’ve created a custom Ecto type for each of the three vector types, e.g. here for int8:

defmodule SqliteVec.Ecto.Int8 do
  @moduledoc """
  `Ecto.Type` for `SqliteVec.Int8`
  """
  use Ecto.Type

  def type, do: :binary

  def cast(value) do
    {:ok, SqliteVec.Int8.new(value)}
  end

  def load(data) do
    {:ok, SqliteVec.Int8.from_binary(data)}
  end

  def dump(%SqliteVec.Int8{} = vector) do
    {:ok, SqliteVec.Int8.to_binary(vector)}
  end

  def dump(_), do: :error
end

What I want to achieve is inserting vectors with regular Ecto.Repo functions.

For that, I define a schema:

defmodule VT do
  use Ecto.Schema

  schema "vt" do
    field(:embedding, SqliteVec.Ecto.Int8)
  end
end	

And now I want to insert using

MyApp.Repo.insert(%VT{
  embedding: SqliteVec.Int8.new([1, 2])
})  

The problem is that this fails as I’m dumping the binary data directly instead of calling the vec_int8 constructor function.
Actually, sqlite-vec interprets plain binary data as float32 (as if I would call the vec_f32 constructor function).
So it works for float32 vectors without constructor function but fails for int8 and bit vectors because the types don’t match.

What I’ve tried:

  • parameterized types, I don’t think they add any capabilities that would work here
  • changing the type of the custom type from :binary to :string and dump a string of the constructor function with interpolated arguments, e.g. “vec_int8(‘[1, 2]’)”

I also had a look at ecto_sqlite3 as I’m assuming that the correct place for this functionality would be the adapter, and in particular the codec.
I guess I would need a way to define my own codec for the custom types, and call the constructor function there, not sure if that would work though.

Thanks in advance for any input!

Showing Posts 1 to 3

rhcarvalho

rhcarvalho

I’m not sure it would work in this context, but have you considered using Ecto’s fragment/1?

LostKobrakai

LostKobrakai

I don‘t think you can merge support like that in from the ecto.type level. The db driver needs to support the column type, which then can be used by an ecto type.

You can take a look host postgrex supports extension for column types (e.g. in geo_postgrex). I‘m not sure if exqlite supports a similar extension system.

joelpaulkoch

joelpaulkoch OP

Thanks for the responses.

I’ve considered using fragment/1 but the problem is where to hook it in.

Thanks for the pointer to postgrex extensions, I’ll look into that if I find the time.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews