use sim_relation_core::{
BindingName, Cell, ColumnName, ConstraintName, FieldName, ParameterName, RelationId, Row,
RowType, SourceName, TableName,
};
use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FieldRef {
pub binding: BindingName,
pub field: FieldName,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NamedScalar {
pub name: FieldName,
pub scalar: Scalar,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NamedAggregate {
pub name: FieldName,
pub aggregate: Aggregate,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum JoinKind {
Inner,
Left,
Cross,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SetOp {
Union,
UnionAll,
Intersect,
Except,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OrderDirection {
Asc,
Desc,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct OrderKey {
pub scalar: Scalar,
pub direction: OrderDirection,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ScalarOp {
And,
Or,
Not,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Add,
Sub,
Mul,
Div,
IsNull,
Coalesce,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Scalar {
Field(FieldRef),
Literal(Cell),
Param(ParameterName),
Call(ScalarOp, Vec<Scalar>),
Case {
branches: Vec<(Scalar, Scalar)>,
otherwise: Option<Box<Scalar>>,
},
Exists(Box<Rel>),
InQuery {
value: Box<Scalar>,
query: Box<Rel>,
},
ScalarQuery(Box<Rel>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Aggregate {
CountAll,
Count(Scalar),
Sum(Scalar),
Min(Scalar),
Max(Scalar),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Rel {
Scan {
source: SourceName,
table: TableName,
bind: BindingName,
},
Values {
bind: BindingName,
row_type: RowType,
rows: Vec<Row>,
},
Project {
input: Box<Rel>,
bind: BindingName,
fields: Vec<NamedScalar>,
},
Filter {
input: Box<Rel>,
predicate: Scalar,
},
Join {
left: Box<Rel>,
right: Box<Rel>,
kind: JoinKind,
on: Scalar,
},
Group {
input: Box<Rel>,
bind: BindingName,
keys: Vec<NamedScalar>,
aggregates: Vec<NamedAggregate>,
having: Option<Scalar>,
},
Set {
op: SetOp,
inputs: Vec<Rel>,
},
Distinct(Box<Rel>),
Order {
input: Box<Rel>,
keys: Vec<OrderKey>,
},
Limit {
input: Box<Rel>,
count: Option<u64>,
offset: u64,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConflictTarget {
PrimaryKey,
UniqueConstraint(ConstraintName),
Columns(Vec<ColumnName>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConflictAction {
Fail,
DoNothing {
target: ConflictTarget,
},
DoUpdate {
target: ConflictTarget,
assignments: Vec<(ColumnName, Scalar)>,
predicate: Option<Scalar>,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Mutation {
Insert {
table: TableName,
columns: Vec<ColumnName>,
input: Box<Rel>,
conflict: ConflictAction,
returning: Vec<NamedScalar>,
},
Update {
table: TableName,
bind: BindingName,
assignments: Vec<(ColumnName, Scalar)>,
predicate: Option<Scalar>,
returning: Vec<NamedScalar>,
},
Delete {
table: TableName,
bind: BindingName,
predicate: Option<Scalar>,
returning: Vec<NamedScalar>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AdmissionLimits {
pub max_literal_rows: usize,
}
impl Default for AdmissionLimits {
fn default() -> Self {
Self {
max_literal_rows: 1024,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AdmissionError {
UnknownTable(TableName),
UnresolvedBinding(BindingName),
AmbiguousBinding(BindingName),
UnresolvedField(FieldRef),
UnresolvedParameter(ParameterName),
TypeError(&'static str),
IllegalAggregateScope,
IncompatibleSet,
ScalarQueryArity,
UnsafeConflictTarget,
MissingRequiredInsertField(ColumnName),
LiteralRowLimit {
limit: usize,
actual: usize,
},
DuplicateName,
}
impl fmt::Display for AdmissionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
}
}
impl std::error::Error for AdmissionError {}
#[derive(Clone, Debug)]
pub struct CheckedQuery {
pub(crate) schema_id: RelationId,
pub(crate) catalog_id: RelationId,
pub(crate) parameters: RowType,
pub(crate) output: RowType,
pub(crate) plan_id: RelationId,
pub(crate) raw: Rel,
}
impl CheckedQuery {
pub fn schema_id(&self) -> &RelationId {
&self.schema_id
}
pub fn catalog_id(&self) -> &RelationId {
&self.catalog_id
}
pub fn parameters(&self) -> &RowType {
&self.parameters
}
pub fn output(&self) -> &RowType {
&self.output
}
pub fn plan_id(&self) -> &RelationId {
&self.plan_id
}
pub fn plan(&self) -> &Rel {
&self.raw
}
}
#[derive(Clone, Debug)]
pub struct CheckedMutation {
pub(crate) schema_id: RelationId,
pub(crate) catalog_id: RelationId,
pub(crate) parameters: RowType,
pub(crate) output: RowType,
pub(crate) plan_id: RelationId,
pub(crate) raw: Mutation,
}
impl CheckedMutation {
pub fn schema_id(&self) -> &RelationId {
&self.schema_id
}
pub fn catalog_id(&self) -> &RelationId {
&self.catalog_id
}
pub fn parameters(&self) -> &RowType {
&self.parameters
}
pub fn output(&self) -> &RowType {
&self.output
}
pub fn plan_id(&self) -> &RelationId {
&self.plan_id
}
pub fn plan(&self) -> &Mutation {
&self.raw
}
}