use super::token::Span;
#[derive(Debug, Clone, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum Statement {
Select(SelectStmt),
Insert(InsertStmt),
Update(UpdateStmt),
Delete(DeleteStmt),
CreateTable(CreateTableStmt),
DropTable(DropTableStmt),
AlterTable(AlterTableStmt),
CreateIndex(CreateIndexStmt),
DropIndex(DropIndexStmt),
Begin(BeginStmt),
Commit,
Rollback(Option<String>), Savepoint(String),
Release(String),
Explain(Box<Statement>),
DefineScope(DefineScopeStmt),
DefineTablePermissions(DefineTablePermissionsStmt),
RemoveScope(String),
Relate(RelateStmt),
LiveSelect(LiveSelectStmt),
DefineEvent(DefineEventStmt),
}
#[derive(Debug, Clone, PartialEq)]
pub struct SelectStmt {
pub span: Span,
pub distinct: bool,
pub columns: Vec<SelectItem>,
pub from: Option<FromClause>,
pub where_clause: Option<Expr>,
pub group_by: Vec<Expr>,
pub having: Option<Expr>,
pub order_by: Vec<OrderByItem>,
pub limit: Option<Expr>,
pub offset: Option<Expr>,
pub unions: Vec<(SetOp, Box<SelectStmt>)>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SelectItem {
Wildcard,
QualifiedWildcard(String),
Expr { expr: Expr, alias: Option<String> },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SetOp {
Union,
UnionAll,
Intersect,
IntersectAll,
Except,
ExceptAll,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FromClause {
pub tables: Vec<TableRef>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TableRef {
Table {
name: ObjectName,
alias: Option<String>,
},
Subquery {
query: Box<SelectStmt>,
alias: String,
},
Join {
left: Box<TableRef>,
join_type: JoinType,
right: Box<TableRef>,
condition: Option<JoinCondition>,
},
Function {
name: String,
args: Vec<Expr>,
alias: Option<String>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JoinType {
Inner,
Left,
Right,
Full,
Cross,
}
#[derive(Debug, Clone, PartialEq)]
pub enum JoinCondition {
On(Expr),
Using(Vec<String>),
Natural,
}
#[derive(Debug, Clone, PartialEq)]
pub struct OrderByItem {
pub expr: Expr,
pub asc: bool,
pub nulls_first: Option<bool>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct InsertStmt {
pub span: Span,
pub table: ObjectName,
pub columns: Option<Vec<String>>,
pub source: InsertSource,
pub on_conflict: Option<OnConflict>,
pub returning: Option<Vec<SelectItem>>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum InsertSource {
Values(Vec<Vec<Expr>>),
Query(Box<SelectStmt>),
Default,
}
#[derive(Debug, Clone, PartialEq)]
pub struct OnConflict {
pub target: Option<ConflictTarget>,
pub action: ConflictAction,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConflictTarget {
Columns(Vec<String>),
Constraint(String),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConflictAction {
DoNothing,
DoUpdate(Vec<Assignment>),
DoReplace,
DoAbort,
DoFail,
}
#[derive(Debug, Clone, PartialEq)]
pub struct UpdateStmt {
pub span: Span,
pub table: ObjectName,
pub alias: Option<String>,
pub assignments: Vec<Assignment>,
pub from: Option<FromClause>,
pub where_clause: Option<Expr>,
pub returning: Option<Vec<SelectItem>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Assignment {
pub column: String,
pub value: Expr,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DeleteStmt {
pub span: Span,
pub table: ObjectName,
pub alias: Option<String>,
pub using: Option<FromClause>,
pub where_clause: Option<Expr>,
pub returning: Option<Vec<SelectItem>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CreateTableStmt {
pub span: Span,
pub if_not_exists: bool,
pub name: ObjectName,
pub columns: Vec<ColumnDef>,
pub constraints: Vec<TableConstraint>,
pub options: Vec<TableOption>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ColumnDef {
pub name: String,
pub data_type: DataType,
pub constraints: Vec<ColumnConstraint>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum DataType {
TinyInt,
SmallInt,
Int,
BigInt,
Float,
Double,
Decimal {
precision: Option<u32>,
scale: Option<u32>,
},
Char(Option<u32>),
Varchar(Option<u32>),
Text,
Binary(Option<u32>),
Varbinary(Option<u32>),
Blob,
Date,
Time,
Timestamp,
DateTime,
Interval,
Boolean,
Json,
Jsonb,
Vector(u32), Embedding(u32),
Custom(String),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ColumnConstraint {
NotNull,
Null,
Unique,
PrimaryKey,
Default(Expr),
Check(Expr),
References {
table: ObjectName,
columns: Vec<String>,
on_delete: Option<ReferentialAction>,
on_update: Option<ReferentialAction>,
},
AutoIncrement,
Generated {
expr: Expr,
stored: bool,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum TableConstraint {
PrimaryKey {
name: Option<String>,
columns: Vec<String>,
},
Unique {
name: Option<String>,
columns: Vec<String>,
},
ForeignKey {
name: Option<String>,
columns: Vec<String>,
ref_table: ObjectName,
ref_columns: Vec<String>,
on_delete: Option<ReferentialAction>,
on_update: Option<ReferentialAction>,
},
Check {
name: Option<String>,
expr: Expr,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReferentialAction {
NoAction,
Restrict,
Cascade,
SetNull,
SetDefault,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TableOption {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DropTableStmt {
pub span: Span,
pub if_exists: bool,
pub names: Vec<ObjectName>,
pub cascade: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AlterTableStmt {
pub span: Span,
pub name: ObjectName,
pub operations: Vec<AlterTableOp>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AlterTableOp {
AddColumn(ColumnDef),
DropColumn {
name: String,
cascade: bool,
},
AlterColumn {
name: String,
operation: AlterColumnOp,
},
AddConstraint(TableConstraint),
DropConstraint {
name: String,
cascade: bool,
},
RenameTable(ObjectName),
RenameColumn {
old_name: String,
new_name: String,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum AlterColumnOp {
SetType(DataType),
SetNotNull,
DropNotNull,
SetDefault(Expr),
DropDefault,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CreateIndexStmt {
pub span: Span,
pub unique: bool,
pub if_not_exists: bool,
pub name: String,
pub table: ObjectName,
pub columns: Vec<IndexColumn>,
pub where_clause: Option<Expr>,
pub index_type: Option<IndexType>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct IndexColumn {
pub name: String,
pub asc: bool,
pub nulls_first: Option<bool>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IndexType {
BTree,
Hash,
Gin,
Gist,
Hnsw, Vamana, }
#[derive(Debug, Clone, PartialEq)]
pub struct DropIndexStmt {
pub span: Span,
pub if_exists: bool,
pub name: String,
pub table: Option<ObjectName>,
pub cascade: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BeginStmt {
pub read_only: bool,
pub isolation_level: Option<IsolationLevel>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IsolationLevel {
ReadUncommitted,
ReadCommitted,
RepeatableRead,
Serializable,
Snapshot,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ObjectName {
pub parts: Vec<String>,
}
impl ObjectName {
pub fn new(name: impl Into<String>) -> Self {
Self {
parts: vec![name.into()],
}
}
pub fn qualified(schema: impl Into<String>, name: impl Into<String>) -> Self {
Self {
parts: vec![schema.into(), name.into()],
}
}
pub fn name(&self) -> &str {
self.parts.last().map(|s| s.as_str()).unwrap_or("")
}
pub fn schema(&self) -> Option<&str> {
if self.parts.len() > 1 {
Some(&self.parts[self.parts.len() - 2])
} else {
None
}
}
}
impl std::fmt::Display for ObjectName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.parts.join("."))
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Literal(Literal),
Column(ColumnRef),
BinaryOp {
left: Box<Expr>,
op: BinaryOperator,
right: Box<Expr>,
},
UnaryOp { op: UnaryOperator, expr: Box<Expr> },
Function(FunctionCall),
Case {
operand: Option<Box<Expr>>,
conditions: Vec<(Expr, Expr)>, else_result: Option<Box<Expr>>,
},
Subquery(Box<SelectStmt>),
Exists(Box<SelectStmt>),
InList {
expr: Box<Expr>,
list: Vec<Expr>,
negated: bool,
},
InSubquery {
expr: Box<Expr>,
subquery: Box<SelectStmt>,
negated: bool,
},
Between {
expr: Box<Expr>,
low: Box<Expr>,
high: Box<Expr>,
negated: bool,
},
Like {
expr: Box<Expr>,
pattern: Box<Expr>,
escape: Option<Box<Expr>>,
negated: bool,
},
IsNull { expr: Box<Expr>, negated: bool },
Cast {
expr: Box<Expr>,
data_type: DataType,
},
Placeholder(u32),
Array(Vec<Expr>),
Tuple(Vec<Expr>),
Subscript { expr: Box<Expr>, index: Box<Expr> },
Vector(Vec<f32>),
VectorSearch {
column: Box<Expr>,
query: Box<Expr>,
k: u32,
metric: VectorMetric,
},
JsonAccess {
expr: Box<Expr>,
path: Box<Expr>,
return_text: bool, },
ContextWindow {
source: Box<Expr>,
max_tokens: u32,
priority: Option<Box<Expr>>,
},
RecordId {
table: String,
id: Box<Expr>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum Literal {
Null,
Boolean(bool),
Integer(i64),
Float(f64),
String(String),
Blob(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ColumnRef {
pub table: Option<String>,
pub column: String,
}
impl ColumnRef {
pub fn new(column: impl Into<String>) -> Self {
Self {
table: None,
column: column.into(),
}
}
pub fn qualified(table: impl Into<String>, column: impl Into<String>) -> Self {
Self {
table: Some(table.into()),
column: column.into(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOperator {
Plus,
Minus,
Multiply,
Divide,
Modulo,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
And,
Or,
Concat,
Like,
BitAnd,
BitOr,
BitXor,
LeftShift,
RightShift,
GraphRight, GraphLeft, GraphBi, }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOperator {
Plus,
Minus,
Not,
BitNot,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FunctionCall {
pub name: ObjectName,
pub args: Vec<Expr>,
pub distinct: bool,
pub filter: Option<Box<Expr>>,
pub over: Option<WindowSpec>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WindowSpec {
pub partition_by: Vec<Expr>,
pub order_by: Vec<OrderByItem>,
pub frame: Option<WindowFrame>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WindowFrame {
pub kind: WindowFrameKind,
pub start: WindowFrameBound,
pub end: Option<WindowFrameBound>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WindowFrameKind {
Rows,
Range,
Groups,
}
#[derive(Debug, Clone, PartialEq)]
pub enum WindowFrameBound {
CurrentRow,
Preceding(Option<Box<Expr>>), Following(Option<Box<Expr>>), }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum VectorMetric {
#[default]
Cosine,
Euclidean,
DotProduct,
Manhattan,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DefineScopeStmt {
pub name: String,
pub session_duration_secs: Option<u64>,
pub signin: Option<Box<Expr>>,
pub signup: Option<Box<Expr>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DefineTablePermissionsStmt {
pub table: ObjectName,
pub permissions: Vec<TablePermission>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TablePermission {
pub operation: PermissionOp,
pub condition: Expr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermissionOp {
Select,
Create,
Update,
Delete,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RelateStmt {
pub span: Span,
pub from: Expr,
pub edge: ObjectName,
pub to: Expr,
pub set: Vec<Assignment>,
pub content: Option<Expr>,
pub returning: Option<Vec<SelectItem>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LiveSelectStmt {
pub span: Span,
pub select: SelectStmt,
pub diff: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DefineEventStmt {
pub span: Span,
pub name: String,
pub table: ObjectName,
pub condition: Expr,
pub action: Expr,
}