I'm trying to use pgvector with exposed, but running into a few issues. Here was my attempt: ```clas...
m

martmists

over 1 year ago
I'm trying to use pgvector with exposed, but running into a few issues. Here was my attempt:
class PgVectorColumnType(private val size: Int) : ColumnType() {
    override fun sqlType(): String = "vector($size)"

    override fun validateValueBeforeUpdate(value: Any?) {
        if (value !is Embedding) error("Value must be an Embedding")
        require(value.vector().size == size) { "Embedding size must be $size" }
    }

    override fun valueFromDB(value: Any) = when (value) {
        is String -> Embedding(value.substring(1, value.length - 1)
                                    .split(",")
                                    .map(String::toFloat)
                                    .toFloatArray())
        else -> value
    }

    override fun valueToDB(value: Any?): Any? {
        if (value == null) return value
        return notNullValueToDB(value)
    }

    override fun notNullValueToDB(value: Any): Any {
        require(value is Embedding) { "Value must be an Embedding" }
        require(value.vector().size == size) { "Embedding size must be $size" }
        return "'${value.vector().contentToString()}'"
    }
}

fun Table.vector(name: String, size: Int): Column<Embedding> = registerColumn(name, PgVectorColumnType(size))
But trying to insert data results in the following error:
Transaction attempt #1 failed: org.postgresql.util.PSQLException: ERROR: column "embedding" is of type vector but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 46. Statement(s): INSERT INTO notes (embedding, title) VALUES (?, ?)
However, manually running the command in the IJ Database Console works just fine.