More resolve stage aggregate defs

This commit is contained in:
2026-05-06 15:18:40 -06:00
parent dea394b681
commit ccb3e52a36

View File

@@ -22,7 +22,9 @@
use std::{collections::BTreeMap, convert::Infallible, marker::PhantomData, sync::Arc};
use indexmap::IndexSet;
use kerolox_ir::EnumRepr;
use salsa::Update;
use strum::EnumIter;
use crate::prelude::*;
@@ -206,7 +208,8 @@ pub fn expr<'db>(
relation: loaded.insert_full(relation_name(db, apply.head.clone())).0,
}))),
ast::ExprExtra::Aggregate(aggregate) => todo!(),
// aggregate resolution validates the specific operation
ast::ExprExtra::Aggregate(agg) => todo!(),
},
// TODO: handle unreachability better?
@@ -322,3 +325,88 @@ pub struct Apply<'db> {
/// The parameters to the function or query.
pub body: Expr<'db>,
}
/// A resolved aggregate operator.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Aggregate<'db> {
/// The resolved kind of aggregate operator.
pub kind: AggregateKind,
/// The list of witnesses (variable indices) to the body.
pub witnesses: Vec<WithAst<usize>>,
/// The body of the aggregate.
pub body: AggregateBody<'db>,
}
/// A resolved aggregate operator kind.
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum AggregateKind {
/// A "bound" aggregate: selects a variable to perform the aggregate over.
Bound {
/// The kind of aggregate operator.
kind: WithAst<BoundAggregateKind>,
/// The index of the variable to bind over.
variable: WithAst<usize>,
},
/// An "unbound" aggregate: no variable needs to be selected to perform the operation.
Unbound {
/// The kind of aggregate operator.
kind: WithAst<UnboundAggregateKind>,
},
/// The aggregate name could not be resolved.
Unknown(WithAst<String>),
}
/// A bound aggregate operator.
#[derive(Copy, Clone, PartialEq, Eq, Hash, EnumIter)]
pub enum BoundAggregateKind {
Sum,
Average,
Min,
Max,
}
impl EnumRepr for BoundAggregateKind {
fn repr(&self) -> &'static str {
use BoundAggregateKind::*;
match self {
Sum => "sum",
Average => "average",
Min => "min",
Max => "max",
}
}
}
/// An unbound aggregate operator.
#[derive(Copy, Clone, PartialEq, Eq, Hash, EnumIter)]
pub enum UnboundAggregateKind {
Count,
Any,
All,
}
impl EnumRepr for UnboundAggregateKind {
fn repr(&self) -> &'static str {
use UnboundAggregateKind::*;
match self {
Count => "count",
Any => "any",
All => "all",
}
}
}
/// An aggregate operator's body.
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum AggregateBody<'db> {
/// A single application operation.
Apply(Apply<'db>),
/// A list of clauses, like in a [RuleBody].
Body(Vec<Expr<'db>>),
}