use crate::ast::{
AggFunc, AggregateMode, AlterAction, Assignment, Expr, GroupKey, JoinKind, Literal, WindowFunc,
};
use powdb_storage::stored_json_path::StoredJsonPathV1;
#[derive(Debug, Clone)]
pub struct CreateField {
pub name: String,
pub type_name: String,
pub required: bool,
pub unique: bool,
pub default: Option<Literal>,
pub auto: bool,
}
#[derive(Debug, Clone)]
pub enum PlanNode {
SeqScan {
table: String,
},
AliasScan {
table: String,
alias: String,
},
IndexScan {
table: String,
column: String,
key: Expr,
},
RangeScan {
table: String,
column: String,
start: Option<(Expr, bool)>,
end: Option<(Expr, bool)>,
},
ExprIndexScan {
table: String,
path: StoredJsonPathV1,
key: Expr,
},
ExprRangeScan {
table: String,
path: StoredJsonPathV1,
start: Option<(Expr, bool)>,
end: Option<(Expr, bool)>,
},
OrderedExprIndexScan {
table: String,
path: StoredJsonPathV1,
descending: bool,
limit: Expr,
offset: Option<Expr>,
},
Filter {
input: Box<PlanNode>,
predicate: Expr,
},
Project {
input: Box<PlanNode>,
fields: Vec<ProjectField>,
},
NestedProject {
input: Box<PlanNode>,
fields: Vec<NestedProjectField>,
},
Sort {
input: Box<PlanNode>,
keys: Vec<SortKey>,
},
Limit {
input: Box<PlanNode>,
count: Expr,
},
Offset {
input: Box<PlanNode>,
count: Expr,
},
Aggregate {
input: Box<PlanNode>,
function: AggFunc,
argument: Option<Expr>,
mode: AggregateMode,
provenance_alias: Option<String>,
},
NestedLoopJoin {
left: Box<PlanNode>,
right: Box<PlanNode>,
on: Option<Expr>,
kind: JoinKind,
},
Distinct {
input: Box<PlanNode>,
},
GroupBy {
input: Box<PlanNode>,
keys: Vec<GroupKey>,
aggregates: Vec<GroupAgg>,
having: Option<Expr>,
},
AlterTable {
table: String,
action: AlterAction,
},
DropTable {
name: String,
if_exists: bool,
},
Insert {
table: String,
rows: Vec<Vec<Assignment>>,
returning: bool,
},
Upsert {
table: String,
key_column: String,
assignments: Vec<Assignment>,
on_conflict: Vec<Assignment>,
},
Update {
input: Box<PlanNode>,
table: String,
assignments: Vec<Assignment>,
returning: bool,
},
Delete {
input: Box<PlanNode>,
table: String,
returning: bool,
},
CreateTable {
name: String,
fields: Vec<CreateField>,
if_not_exists: bool,
},
ListTypes,
Describe {
table: String,
},
CreateView {
name: String,
query_text: String,
},
RefreshView {
name: String,
},
DropView {
name: String,
if_exists: bool,
},
Window {
input: Box<PlanNode>,
windows: Vec<WindowDef>,
},
Union {
left: Box<PlanNode>,
right: Box<PlanNode>,
all: bool,
},
Explain {
input: Box<PlanNode>,
},
Begin,
Commit,
Rollback,
}
#[derive(Debug, Clone)]
pub struct ProjectField {
pub alias: Option<String>,
pub expr: Expr,
}
#[derive(Debug, Clone)]
pub enum NestedProjectField {
Plain(ProjectField),
Nested(Box<NestedProjection>),
}
#[derive(Debug, Clone)]
pub struct NestedProjection {
pub name: String,
pub table: String,
pub alias: String,
pub parent_alias: String,
pub child_key: String,
pub parent_key: String,
pub residual: Option<Expr>,
pub order: Vec<(String, bool)>,
pub limit: Option<Expr>,
pub offset: Option<Expr>,
pub offset_before_limit: bool,
pub fields: Vec<NestedField>,
}
#[derive(Debug, Clone)]
pub enum NestedField {
Scalar { key: String, column: String },
Nested(Box<NestedProjection>),
}
impl NestedProjection {
pub fn visit_tables(&self, visit: &mut dyn FnMut(&str)) {
visit(&self.table);
for field in &self.fields {
if let NestedField::Nested(inner) = field {
inner.visit_tables(visit);
}
}
}
}
#[derive(Debug, Clone)]
pub struct SortKey {
pub expr: Expr,
pub descending: bool,
}
#[derive(Debug, Clone)]
pub struct GroupAgg {
pub function: AggFunc,
pub argument: Expr,
pub mode: AggregateMode,
pub provenance_alias: Option<String>,
pub output_name: String,
}
#[derive(Debug, Clone)]
pub struct WindowDef {
pub function: WindowFunc,
pub args: Vec<Expr>,
pub mode: AggregateMode,
pub partition_by: Vec<Expr>,
pub order_by: Vec<SortKey>,
pub output_name: String,
}