mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-08 09:44:21 +01:00
feat(vector): integrate euclidean distance into limbo
This commit is contained in:
@@ -633,6 +633,7 @@ The `vector` extension is compatible with libSQL native vector search.
|
||||
| vector64(x) | Yes | |
|
||||
| vector_extract(x) | Yes | |
|
||||
| vector_distance_cos(x, y) | Yes | |
|
||||
| distance_l2(x, y) | Yes |Euclidean distance|
|
||||
|
||||
### Time
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ pub enum VectorFunc {
|
||||
Vector64,
|
||||
VectorExtract,
|
||||
VectorDistanceCos,
|
||||
VectorDistanceEuclidean,
|
||||
}
|
||||
|
||||
impl VectorFunc {
|
||||
@@ -172,6 +173,8 @@ impl Display for VectorFunc {
|
||||
Self::Vector64 => "vector64".to_string(),
|
||||
Self::VectorExtract => "vector_extract".to_string(),
|
||||
Self::VectorDistanceCos => "vector_distance_cos".to_string(),
|
||||
// We use `distance_l2` to reduce user input
|
||||
Self::VectorDistanceEuclidean => "distance_l2".to_string(),
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
@@ -814,6 +817,7 @@ impl Func {
|
||||
"vector64" => Ok(Self::Vector(VectorFunc::Vector64)),
|
||||
"vector_extract" => Ok(Self::Vector(VectorFunc::VectorExtract)),
|
||||
"vector_distance_cos" => Ok(Self::Vector(VectorFunc::VectorDistanceCos)),
|
||||
"distance_l2" => Ok(Self::Vector(VectorFunc::VectorDistanceEuclidean)),
|
||||
_ => crate::bail_parse_error!("no such function: {}", name),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,6 +920,19 @@ pub fn translate_expr(
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
VectorFunc::VectorDistanceEuclidean => {
|
||||
let args = expect_arguments_exact!(args, 2, vector_func);
|
||||
let regs = program.alloc_registers(2);
|
||||
translate_expr(program, referenced_tables, &args[0], regs, resolver)?;
|
||||
translate_expr(program, referenced_tables, &args[1], regs + 1, resolver)?;
|
||||
program.emit_insn(Insn::Function {
|
||||
constant_mask: 0,
|
||||
start_reg: regs,
|
||||
dest: target_register,
|
||||
func: func_ctx,
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
},
|
||||
Func::Scalar(srf) => {
|
||||
match srf {
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::{
|
||||
builder::CursorType,
|
||||
insn::{IdxInsertFlags, Insn},
|
||||
},
|
||||
vector::{vector32, vector64, vector_distance_cos, vector_extract},
|
||||
vector::{vector32, vector64, vector_distance_cos, vector_distance_l2, vector_extract},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -3802,6 +3802,11 @@ pub fn op_function(
|
||||
vector_distance_cos(&state.registers[*start_reg..*start_reg + arg_count])?;
|
||||
state.registers[*dest] = Register::Value(result);
|
||||
}
|
||||
VectorFunc::VectorDistanceEuclidean => {
|
||||
let result =
|
||||
vector_distance_l2(&state.registers[*start_reg..*start_reg + arg_count])?;
|
||||
state.registers[*dest] = Register::Value(result);
|
||||
}
|
||||
},
|
||||
crate::function::Func::External(f) => match f.func {
|
||||
ExtFunc::Scalar(f) => {
|
||||
|
||||
@@ -42,7 +42,7 @@ impl DistanceCalculator for Euclidean {
|
||||
_v1: &'a [Vector],
|
||||
_v2: &'a [Vector],
|
||||
) -> Box<dyn Iterator<Item = Result<f64>> + 'a> {
|
||||
unimplemented!();
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::types::Value;
|
||||
use crate::vdbe::Register;
|
||||
use crate::vector::distance::{euclidean::Euclidean, DistanceCalculator};
|
||||
use crate::LimboError;
|
||||
use crate::Result;
|
||||
|
||||
@@ -78,3 +79,16 @@ pub fn vector_distance_cos(args: &[Register]) -> Result<Value> {
|
||||
let dist = do_vector_distance_cos(&x, &y)?;
|
||||
Ok(Value::Float(dist))
|
||||
}
|
||||
|
||||
pub fn vector_distance_l2(args: &[Register]) -> Result<Value> {
|
||||
if args.len() != 2 {
|
||||
return Err(LimboError::ConversionError(
|
||||
"distance_l2 requires exactly two arguments".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let x = parse_vector(&args[0], None)?;
|
||||
let y = parse_vector(&args[1], None)?;
|
||||
let dist = Euclidean::calculate(&[x], &[y])?;
|
||||
Ok(Value::Float(dist))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user