use linkrs_core::types::expr::contextual::ContextualExpression;
use linkrs_core::types::span::Span;
use serde::{Deserialize, Serialize};
use super::stmt::OrderByClause;
use super::types::{LimitClause, SkipClause};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateVectorIndex {
pub span: Span,
pub index_name: String,
pub schema_name: String,
pub field_name: String,
pub config: VectorIndexConfig,
pub if_not_exists: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum QuantizationKind {
Scalar,
Binary,
Product,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum CompressionRatioKind {
X4,
X8,
X16,
X32,
X64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VectorIndexConfig {
pub vector_size: usize,
pub distance: VectorDistance,
pub hnsw_m: Option<usize>,
pub hnsw_ef_construct: Option<usize>,
pub quantization: Option<QuantizationKind>,
pub quantile: Option<f32>,
pub compression: Option<CompressionRatioKind>,
pub always_ram: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropVectorIndex {
pub span: Span,
pub index_name: String,
pub if_exists: bool,
}
#[derive(Debug, Clone)]
pub struct SearchVectorStatement {
pub span: Span,
pub index_name: String,
pub query: VectorQueryExpr,
pub threshold: Option<f32>,
pub where_clause: Option<ContextualExpression>,
pub order_clause: Option<OrderByClause>,
pub limit: Option<LimitClause>,
pub skip: Option<SkipClause>,
pub yield_clause: Option<VectorYieldClause>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VectorQueryExpr {
pub span: Span,
pub query_type: VectorQueryType,
pub query_data: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VectorQueryType {
Vector,
Text,
Parameter,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum VectorDistance {
Cosine,
Euclidean,
Dot,
Manhattan,
}
#[derive(Debug, Clone)]
pub struct VectorYieldClause {
pub items: Vec<VectorYieldItem>,
}
#[derive(Debug, Clone)]
pub struct VectorYieldItem {
pub expr: ContextualExpression,
pub alias: Option<String>,
}
#[derive(Debug, Clone)]
pub struct MatchVector {
pub span: Span,
pub pattern: String,
pub vector_condition: VectorMatchCondition,
pub yield_clause: Option<VectorYieldClause>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VectorMatchCondition {
pub field: String,
pub query: VectorQueryExpr,
pub threshold: Option<f32>,
}
#[derive(Debug, Clone)]
pub struct LookupVector {
pub span: Span,
pub schema_name: String,
pub index_name: String,
pub query: VectorQueryExpr,
pub yield_clause: Option<VectorYieldClause>,
pub limit: Option<usize>,
}
impl CreateVectorIndex {
pub fn new(
span: Span,
index_name: String,
schema_name: String,
field_name: String,
config: VectorIndexConfig,
) -> Self {
Self {
span,
index_name,
schema_name,
field_name,
config,
if_not_exists: false,
}
}
pub fn with_if_not_exists(mut self, if_not_exists: bool) -> Self {
self.if_not_exists = if_not_exists;
self
}
}
impl DropVectorIndex {
pub fn new(span: Span, index_name: String) -> Self {
Self {
span,
index_name,
if_exists: false,
}
}
pub fn with_if_exists(mut self, if_exists: bool) -> Self {
self.if_exists = if_exists;
self
}
}
impl VectorQueryExpr {
pub fn vector(span: Span, vector_str: String) -> Self {
Self {
span,
query_type: VectorQueryType::Vector,
query_data: vector_str,
}
}
pub fn text(span: Span, text: String) -> Self {
Self {
span,
query_type: VectorQueryType::Text,
query_data: text,
}
}
pub fn parameter(span: Span, param_name: String) -> Self {
Self {
span,
query_type: VectorQueryType::Parameter,
query_data: param_name,
}
}
}
impl VectorIndexConfig {
pub fn new(vector_size: usize, distance: VectorDistance) -> Self {
Self {
vector_size,
distance,
hnsw_m: None,
hnsw_ef_construct: None,
quantization: None,
quantile: None,
compression: None,
always_ram: None,
}
}
pub fn with_hnsw(mut self, m: usize, ef_construct: usize) -> Self {
self.hnsw_m = Some(m);
self.hnsw_ef_construct = Some(ef_construct);
self
}
pub fn with_quantization(
mut self,
quantization: QuantizationKind,
quantile: Option<f32>,
compression: Option<CompressionRatioKind>,
always_ram: Option<bool>,
) -> Self {
self.quantization = Some(quantization);
self.quantile = quantile;
self.compression = compression;
self.always_ram = always_ram;
self
}
}
impl CompressionRatioKind {
pub fn as_str(&self) -> &'static str {
match self {
CompressionRatioKind::X4 => "x4",
CompressionRatioKind::X8 => "x8",
CompressionRatioKind::X16 => "x16",
CompressionRatioKind::X32 => "x32",
CompressionRatioKind::X64 => "x64",
}
}
}