#[derive(Debug, Clone)]
pub enum SqlPlan {
ConstantResult {
columns: Vec<String>,
values: Vec<SqlValue>,
},
Scan {
collection: String,
alias: Option<String>,
engine: EngineType,
filters: Vec<Filter>,
projection: Vec<Projection>,
sort_keys: Vec<SortKey>,
limit: Option<usize>,
offset: usize,
distinct: bool,
window_functions: Vec<WindowSpec>,
},
PointGet {
collection: String,
alias: Option<String>,
engine: EngineType,
key_column: String,
key_value: SqlValue,
},
RangeScan {
collection: String,
field: String,
lower: Option<SqlValue>,
upper: Option<SqlValue>,
limit: usize,
},
Insert {
collection: String,
engine: EngineType,
rows: Vec<Vec<(String, SqlValue)>>,
column_defaults: Vec<(String, String)>,
},
KvInsert {
collection: String,
entries: Vec<(SqlValue, Vec<(String, SqlValue)>)>,
ttl_secs: u64,
},
Upsert {
collection: String,
engine: EngineType,
rows: Vec<Vec<(String, SqlValue)>>,
column_defaults: Vec<(String, String)>,
on_conflict_updates: Vec<(String, SqlExpr)>,
},
InsertSelect {
target: String,
source: Box<SqlPlan>,
limit: usize,
},
Update {
collection: String,
engine: EngineType,
assignments: Vec<(String, SqlExpr)>,
filters: Vec<Filter>,
target_keys: Vec<SqlValue>,
returning: bool,
},
Delete {
collection: String,
engine: EngineType,
filters: Vec<Filter>,
target_keys: Vec<SqlValue>,
},
Truncate {
collection: String,
restart_identity: bool,
},
Join {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
on: Vec<(String, String)>,
join_type: JoinType,
condition: Option<SqlExpr>,
limit: usize,
projection: Vec<Projection>,
filters: Vec<Filter>,
},
Aggregate {
input: Box<SqlPlan>,
group_by: Vec<SqlExpr>,
aggregates: Vec<AggregateExpr>,
having: Vec<Filter>,
limit: usize,
},
TimeseriesScan {
collection: String,
time_range: (i64, i64),
bucket_interval_ms: i64,
group_by: Vec<String>,
aggregates: Vec<AggregateExpr>,
filters: Vec<Filter>,
projection: Vec<Projection>,
gap_fill: String,
limit: usize,
tiered: bool,
},
TimeseriesIngest {
collection: String,
rows: Vec<Vec<(String, SqlValue)>>,
},
VectorSearch {
collection: String,
field: String,
query_vector: Vec<f32>,
top_k: usize,
ef_search: usize,
filters: Vec<Filter>,
},
MultiVectorSearch {
collection: String,
query_vector: Vec<f32>,
top_k: usize,
ef_search: usize,
},
TextSearch {
collection: String,
query: String,
top_k: usize,
fuzzy: bool,
filters: Vec<Filter>,
},
HybridSearch {
collection: String,
query_vector: Vec<f32>,
query_text: String,
top_k: usize,
ef_search: usize,
vector_weight: f32,
fuzzy: bool,
},
SpatialScan {
collection: String,
field: String,
predicate: SpatialPredicate,
query_geometry: Vec<u8>,
distance_meters: f64,
attribute_filters: Vec<Filter>,
limit: usize,
projection: Vec<Projection>,
},
Union {
inputs: Vec<SqlPlan>,
distinct: bool,
},
Intersect {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
all: bool,
},
Except {
left: Box<SqlPlan>,
right: Box<SqlPlan>,
all: bool,
},
RecursiveScan {
collection: String,
base_filters: Vec<Filter>,
recursive_filters: Vec<Filter>,
max_iterations: usize,
distinct: bool,
limit: usize,
},
Cte {
definitions: Vec<(String, SqlPlan)>,
outer: Box<SqlPlan>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EngineType {
DocumentSchemaless,
DocumentStrict,
KeyValue,
Columnar,
Timeseries,
Spatial,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JoinType {
Inner,
Left,
Right,
Full,
Semi,
Anti,
Cross,
}
impl JoinType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Inner => "inner",
Self::Left => "left",
Self::Right => "right",
Self::Full => "full",
Self::Semi => "semi",
Self::Anti => "anti",
Self::Cross => "cross",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SpatialPredicate {
DWithin,
Contains,
Intersects,
Within,
}
#[derive(Debug, Clone)]
pub struct Filter {
pub expr: FilterExpr,
}
#[derive(Debug, Clone)]
pub enum FilterExpr {
Comparison {
field: String,
op: CompareOp,
value: SqlValue,
},
Like {
field: String,
pattern: String,
},
InList {
field: String,
values: Vec<SqlValue>,
},
Between {
field: String,
low: SqlValue,
high: SqlValue,
},
IsNull {
field: String,
},
IsNotNull {
field: String,
},
And(Vec<Filter>),
Or(Vec<Filter>),
Not(Box<Filter>),
Expr(SqlExpr),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
Eq,
Ne,
Gt,
Ge,
Lt,
Le,
}
#[derive(Debug, Clone)]
pub enum Projection {
Column(String),
Star,
QualifiedStar(String),
Computed { expr: SqlExpr, alias: String },
}
#[derive(Debug, Clone)]
pub struct SortKey {
pub expr: SqlExpr,
pub ascending: bool,
pub nulls_first: bool,
}
#[derive(Debug, Clone)]
pub struct AggregateExpr {
pub function: String,
pub args: Vec<SqlExpr>,
pub alias: String,
pub distinct: bool,
}
#[derive(Debug, Clone)]
pub struct WindowSpec {
pub function: String,
pub args: Vec<SqlExpr>,
pub partition_by: Vec<SqlExpr>,
pub order_by: Vec<SortKey>,
pub alias: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SqlValue {
Int(i64),
Float(f64),
String(String),
Bool(bool),
Null,
Bytes(Vec<u8>),
Array(Vec<SqlValue>),
}
#[derive(Debug, Clone)]
pub enum SqlExpr {
Column { table: Option<String>, name: String },
Literal(SqlValue),
BinaryOp {
left: Box<SqlExpr>,
op: BinaryOp,
right: Box<SqlExpr>,
},
UnaryOp { op: UnaryOp, expr: Box<SqlExpr> },
Function {
name: String,
args: Vec<SqlExpr>,
distinct: bool,
},
Case {
operand: Option<Box<SqlExpr>>,
when_then: Vec<(SqlExpr, SqlExpr)>,
else_expr: Option<Box<SqlExpr>>,
},
Cast { expr: Box<SqlExpr>, to_type: String },
Subquery(Box<SqlPlan>),
Wildcard,
IsNull { expr: Box<SqlExpr>, negated: bool },
InList {
expr: Box<SqlExpr>,
list: Vec<SqlExpr>,
negated: bool,
},
Between {
expr: Box<SqlExpr>,
low: Box<SqlExpr>,
high: Box<SqlExpr>,
negated: bool,
},
Like {
expr: Box<SqlExpr>,
pattern: Box<SqlExpr>,
negated: bool,
},
ArrayLiteral(Vec<SqlExpr>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
Add,
Sub,
Mul,
Div,
Mod,
Eq,
Ne,
Gt,
Ge,
Lt,
Le,
And,
Or,
Concat,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Neg,
Not,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SqlDataType {
Int64,
Float64,
String,
Bool,
Bytes,
Timestamp,
Decimal,
Uuid,
Vector(usize),
Geometry,
}
pub use crate::catalog::{SqlCatalog, SqlCatalogError};
#[derive(Debug, Clone)]
pub struct CollectionInfo {
pub name: String,
pub engine: EngineType,
pub columns: Vec<ColumnInfo>,
pub primary_key: Option<String>,
pub has_auto_tier: bool,
}
#[derive(Debug, Clone)]
pub struct ColumnInfo {
pub name: String,
pub data_type: SqlDataType,
pub nullable: bool,
pub is_primary_key: bool,
pub default: Option<String>,
}