fix(go.sum): update ResolveSpec dependency to v1.0.87
This commit is contained in:
+128
@@ -0,0 +1,128 @@
|
||||
package pgx
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/pgvector/pgvector-go"
|
||||
"github.com/x448/float16"
|
||||
)
|
||||
|
||||
type HalfVectorCodec struct{}
|
||||
|
||||
func (HalfVectorCodec) FormatSupported(format int16) bool {
|
||||
return format == pgx.BinaryFormatCode || format == pgx.TextFormatCode
|
||||
}
|
||||
|
||||
func (HalfVectorCodec) PreferredFormat() int16 {
|
||||
return pgx.BinaryFormatCode
|
||||
}
|
||||
|
||||
func (HalfVectorCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, value any) pgtype.EncodePlan {
|
||||
_, ok := value.(pgvector.HalfVector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return encodePlanHalfVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return encodePlanHalfVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type encodePlanHalfVectorCodecBinary struct{}
|
||||
|
||||
func (encodePlanHalfVectorCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.HalfVector)
|
||||
vec := v.Slice()
|
||||
dim := len(vec)
|
||||
buf = slices.Grow(buf, 4+2*dim)
|
||||
buf = binary.BigEndian.AppendUint16(buf, uint16(dim))
|
||||
buf = binary.BigEndian.AppendUint16(buf, 0)
|
||||
for _, v := range vec {
|
||||
buf = binary.BigEndian.AppendUint16(buf, float16.Fromfloat32(v).Bits())
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type encodePlanHalfVectorCodecText struct{}
|
||||
|
||||
func (encodePlanHalfVectorCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.HalfVector)
|
||||
return v.EncodeText(buf)
|
||||
}
|
||||
|
||||
func (HalfVectorCodec) PlanScan(m *pgtype.Map, oid uint32, format int16, target any) pgtype.ScanPlan {
|
||||
_, ok := target.(*pgvector.HalfVector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return scanPlanHalfVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return scanPlanHalfVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type scanPlanHalfVectorCodecBinary struct{}
|
||||
|
||||
func (scanPlanHalfVectorCodecBinary) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.HalfVector)
|
||||
buf := src
|
||||
dim := int(binary.BigEndian.Uint16(buf[0:2]))
|
||||
unused := binary.BigEndian.Uint16(buf[2:4])
|
||||
if unused != 0 {
|
||||
return fmt.Errorf("expected unused to be 0")
|
||||
}
|
||||
|
||||
vec := make([]float32, 0, dim)
|
||||
offset := 4
|
||||
for i := 0; i < dim; i++ {
|
||||
vec = append(vec, float16.Frombits(binary.BigEndian.Uint16(buf[offset:offset+2])).Float32())
|
||||
offset += 2
|
||||
}
|
||||
v.SetSlice(vec)
|
||||
return nil
|
||||
}
|
||||
|
||||
type scanPlanHalfVectorCodecText struct{}
|
||||
|
||||
func (scanPlanHalfVectorCodecText) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.HalfVector)
|
||||
return v.Scan(src)
|
||||
}
|
||||
|
||||
func (c HalfVectorCodec) DecodeDatabaseSQLValue(m *pgtype.Map, oid uint32, format int16, src []byte) (driver.Value, error) {
|
||||
return c.DecodeValue(m, oid, format, src)
|
||||
}
|
||||
|
||||
func (c HalfVectorCodec) DecodeValue(m *pgtype.Map, oid uint32, format int16, src []byte) (any, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var vec pgvector.HalfVector
|
||||
scanPlan := c.PlanScan(m, oid, format, &vec)
|
||||
if scanPlan == nil {
|
||||
return nil, fmt.Errorf("Unable to decode halfvec type")
|
||||
}
|
||||
|
||||
err := scanPlan.Scan(src, &vec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vec, nil
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package pgx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func RegisterTypes(ctx context.Context, conn *pgx.Conn) error {
|
||||
var vectorOid *uint32
|
||||
var vectorArrayOid *uint32
|
||||
var halfvecOid *uint32
|
||||
var halfvecArrayOid *uint32
|
||||
var sparsevecOid *uint32
|
||||
var sparsevecArrayOid *uint32
|
||||
err := conn.QueryRow(ctx, "SELECT to_regtype('vector')::oid, to_regtype('_vector')::oid, to_regtype('halfvec')::oid, to_regtype('_halfvec')::oid, to_regtype('sparsevec')::oid, to_regtype('_sparsevec')::oid").Scan(&vectorOid, &vectorArrayOid, &halfvecOid, &halfvecArrayOid, &sparsevecOid, &sparsevecArrayOid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if vectorOid == nil {
|
||||
return fmt.Errorf("vector type not found in the database")
|
||||
}
|
||||
|
||||
tm := conn.TypeMap()
|
||||
registerType(tm, "vector", vectorOid, vectorArrayOid, &VectorCodec{})
|
||||
|
||||
if halfvecOid != nil {
|
||||
registerType(tm, "halfvec", halfvecOid, halfvecArrayOid, &HalfVectorCodec{})
|
||||
}
|
||||
|
||||
if sparsevecOid != nil {
|
||||
registerType(tm, "sparsevec", sparsevecOid, sparsevecArrayOid, &SparseVectorCodec{})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerType(tm *pgtype.Map, name string, oid *uint32, arrayOid *uint32, codec pgtype.Codec) {
|
||||
t := pgtype.Type{Name: name, OID: *oid, Codec: codec}
|
||||
tm.RegisterType(&t)
|
||||
|
||||
// should never be nil
|
||||
if arrayOid != nil {
|
||||
tm.RegisterType(&pgtype.Type{Name: "_" + name, OID: *arrayOid, Codec: &pgtype.ArrayCodec{ElementType: &t}})
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package pgx
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/pgvector/pgvector-go"
|
||||
)
|
||||
|
||||
type SparseVectorCodec struct{}
|
||||
|
||||
func (SparseVectorCodec) FormatSupported(format int16) bool {
|
||||
return format == pgx.BinaryFormatCode || format == pgx.TextFormatCode
|
||||
}
|
||||
|
||||
func (SparseVectorCodec) PreferredFormat() int16 {
|
||||
return pgx.BinaryFormatCode
|
||||
}
|
||||
|
||||
func (SparseVectorCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, value any) pgtype.EncodePlan {
|
||||
_, ok := value.(pgvector.SparseVector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return encodePlanSparseVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return encodePlanSparseVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type encodePlanSparseVectorCodecBinary struct{}
|
||||
|
||||
func (encodePlanSparseVectorCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.SparseVector)
|
||||
return v.EncodeBinary(buf)
|
||||
}
|
||||
|
||||
type encodePlanSparseVectorCodecText struct{}
|
||||
|
||||
func (encodePlanSparseVectorCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.SparseVector)
|
||||
// use String() for now to avoid adding another method to SparseVector
|
||||
return append(buf, v.String()...), nil
|
||||
}
|
||||
|
||||
func (SparseVectorCodec) PlanScan(m *pgtype.Map, oid uint32, format int16, target any) pgtype.ScanPlan {
|
||||
_, ok := target.(*pgvector.SparseVector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return scanPlanSparseVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return scanPlanSparseVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type scanPlanSparseVectorCodecBinary struct{}
|
||||
|
||||
func (scanPlanSparseVectorCodecBinary) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.SparseVector)
|
||||
return v.DecodeBinary(src)
|
||||
}
|
||||
|
||||
type scanPlanSparseVectorCodecText struct{}
|
||||
|
||||
func (scanPlanSparseVectorCodecText) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.SparseVector)
|
||||
return v.Scan(src)
|
||||
}
|
||||
|
||||
func (c SparseVectorCodec) DecodeDatabaseSQLValue(m *pgtype.Map, oid uint32, format int16, src []byte) (driver.Value, error) {
|
||||
return c.DecodeValue(m, oid, format, src)
|
||||
}
|
||||
|
||||
func (c SparseVectorCodec) DecodeValue(m *pgtype.Map, oid uint32, format int16, src []byte) (any, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var vec pgvector.SparseVector
|
||||
scanPlan := c.PlanScan(m, oid, format, &vec)
|
||||
if scanPlan == nil {
|
||||
return nil, fmt.Errorf("Unable to decode sparsevec type")
|
||||
}
|
||||
|
||||
err := scanPlan.Scan(src, &vec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vec, nil
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package pgx
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/pgvector/pgvector-go"
|
||||
)
|
||||
|
||||
type VectorCodec struct{}
|
||||
|
||||
func (VectorCodec) FormatSupported(format int16) bool {
|
||||
return format == pgx.BinaryFormatCode || format == pgx.TextFormatCode
|
||||
}
|
||||
|
||||
func (VectorCodec) PreferredFormat() int16 {
|
||||
return pgx.BinaryFormatCode
|
||||
}
|
||||
|
||||
func (VectorCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, value any) pgtype.EncodePlan {
|
||||
_, ok := value.(pgvector.Vector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return encodePlanVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return encodePlanVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type encodePlanVectorCodecBinary struct{}
|
||||
|
||||
func (encodePlanVectorCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.Vector)
|
||||
return v.EncodeBinary(buf)
|
||||
}
|
||||
|
||||
type encodePlanVectorCodecText struct{}
|
||||
|
||||
func (encodePlanVectorCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||
v := value.(pgvector.Vector)
|
||||
// use String() for now to avoid adding another method to Vector
|
||||
return append(buf, v.String()...), nil
|
||||
}
|
||||
|
||||
func (VectorCodec) PlanScan(m *pgtype.Map, oid uint32, format int16, target any) pgtype.ScanPlan {
|
||||
_, ok := target.(*pgvector.Vector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch format {
|
||||
case pgx.BinaryFormatCode:
|
||||
return scanPlanVectorCodecBinary{}
|
||||
case pgx.TextFormatCode:
|
||||
return scanPlanVectorCodecText{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type scanPlanVectorCodecBinary struct{}
|
||||
|
||||
func (scanPlanVectorCodecBinary) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.Vector)
|
||||
return v.DecodeBinary(src)
|
||||
}
|
||||
|
||||
type scanPlanVectorCodecText struct{}
|
||||
|
||||
func (scanPlanVectorCodecText) Scan(src []byte, dst any) error {
|
||||
v := (dst).(*pgvector.Vector)
|
||||
return v.Scan(src)
|
||||
}
|
||||
|
||||
func (c VectorCodec) DecodeDatabaseSQLValue(m *pgtype.Map, oid uint32, format int16, src []byte) (driver.Value, error) {
|
||||
return c.DecodeValue(m, oid, format, src)
|
||||
}
|
||||
|
||||
func (c VectorCodec) DecodeValue(m *pgtype.Map, oid uint32, format int16, src []byte) (any, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var vec pgvector.Vector
|
||||
scanPlan := c.PlanScan(m, oid, format, &vec)
|
||||
if scanPlan == nil {
|
||||
return nil, fmt.Errorf("Unable to decode vector type")
|
||||
}
|
||||
|
||||
err := scanPlan.Scan(src, &vec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vec, nil
|
||||
}
|
||||
Reference in New Issue
Block a user