use serde::{Deserialize, Serialize};
use super::fusion::FusionConfig;
use super::values::{Value, VectorExpr};
use crate::sparse_index::SparseVector;
use crate::velesql::GraphPattern;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Condition {
VectorSearch(VectorSearch),
VectorFusedSearch(VectorFusedSearch),
SparseVectorSearch(SparseVectorSearch),
Similarity(SimilarityCondition),
Comparison(Comparison),
In(InCondition),
Between(BetweenCondition),
Like(LikeCondition),
IsNull(IsNullCondition),
Match(MatchCondition),
GraphMatch(GraphMatchPredicate),
Contains(ContainsCondition),
ContainsText(ContainsTextCondition),
GeoDistance(GeoDistanceCondition),
GeoBbox(GeoBboxCondition),
And(Box<Condition>, Box<Condition>),
Or(Box<Condition>, Box<Condition>),
Not(Box<Condition>),
Group(Box<Condition>),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GraphMatchPredicate {
pub pattern: GraphPattern,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VectorSearch {
pub vector: VectorExpr,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VectorFusedSearch {
pub vectors: Vec<VectorExpr>,
pub fusion: FusionConfig,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SparseVectorSearch {
pub vector: SparseVectorExpr,
pub index_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum SparseVectorExpr {
Literal(SparseVector),
Parameter(String),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SimilarityCondition {
pub field: String,
pub vector: VectorExpr,
pub operator: CompareOp,
pub threshold: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Comparison {
pub column: String,
pub operator: CompareOp,
pub value: Value,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum CompareOp {
Eq,
NotEq,
Gt,
Gte,
Lt,
Lte,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct InCondition {
pub column: String,
pub values: Vec<Value>,
#[serde(default)]
pub negated: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BetweenCondition {
pub column: String,
pub low: Value,
pub high: Value,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LikeCondition {
pub column: String,
pub pattern: String,
#[serde(default)]
pub case_insensitive: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IsNullCondition {
pub column: String,
pub is_null: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MatchCondition {
pub column: String,
pub query: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ContainsTextCondition {
pub column: String,
pub query: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ContainsMode {
Single,
Any,
All,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ContainsCondition {
pub column: String,
pub mode: ContainsMode,
pub values: Vec<Value>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GeoDistanceCondition {
pub column: String,
pub lat: f64,
pub lng: f64,
pub operator: CompareOp,
pub threshold: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GeoBboxCondition {
pub column: String,
pub lat_min: f64,
pub lng_min: f64,
pub lat_max: f64,
pub lng_max: f64,
}
impl Condition {
#[must_use]
pub fn has_vector_search(&self) -> bool {
match self {
Self::VectorSearch(_) | Self::VectorFusedSearch(_) | Self::SparseVectorSearch(_) => {
true
}
Self::And(l, r) | Self::Or(l, r) => l.has_vector_search() || r.has_vector_search(),
Self::Group(inner) | Self::Not(inner) => inner.has_vector_search(),
Self::Contains(_)
| Self::ContainsText(_)
| Self::Comparison(_)
| Self::In(_)
| Self::Between(_)
| Self::Like(_)
| Self::IsNull(_)
| Self::Match(_)
| Self::GraphMatch(_)
| Self::Similarity(_)
| Self::GeoDistance(_)
| Self::GeoBbox(_) => false,
}
}
}