feat(vector): integrate euclidean distance into limbo

This commit is contained in:
KaguraMilet
2025-07-07 21:08:24 +08:00
parent d49707a80d
commit ac95758f76
6 changed files with 39 additions and 2 deletions

View File

@@ -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

View File

@@ -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),
}
}

View File

@@ -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 {

View File

@@ -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) => {

View File

@@ -42,7 +42,7 @@ impl DistanceCalculator for Euclidean {
_v1: &'a [Vector],
_v2: &'a [Vector],
) -> Box<dyn Iterator<Item = Result<f64>> + 'a> {
unimplemented!();
todo!()
}
}

View File

@@ -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))
}