#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub struct Query {
pub distinct: bool,
pub select: Vec<SelectItem>,
pub select_aliases: Vec<Option<String>>,
pub retained_set: bool,
pub from: FromSource,
pub alias: Option<String>,
pub where_: Option<Predicate>,
pub order_by: Option<OrderBy>,
pub limit: Option<u64>,
pub offset: Option<u64>,
pub union_branches: Vec<Query>,
pub union_limit: Option<u64>,
pub group_by: Vec<Expr>,
pub having: Option<Predicate>,
pub intersect_branches: Vec<Query>,
pub except_branches: Vec<Query>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum SortDir {
Asc,
Desc,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub struct OrderBy {
pub key: Attr,
pub dir: SortDir,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum SelectItem {
Star,
Attr(Attr),
Aggregate { func: AggFunc, arg: Box<SelectItem> },
Path { from: PathOperand, to: PathOperand },
ToString(String),
Expr(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum PathOperand {
Alias(String),
Class(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum AggFunc {
Count,
Sum,
Min,
Max,
Avg,
Percentile(u8),
Median,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum Attr {
ObjectId,
ObjectAddress,
UsedHeapSize,
RetainedHeapSize,
DisplayName,
Length,
Inbounds,
Outbounds,
ClassOf,
Dominators(String),
DominatorOf(String),
ToString(String),
ToHex(Box<Expr>),
Field(String),
RefPath {
hops: Vec<String>,
tail: Box<Attr>,
role: RefRole,
},
ValueArray,
ReferenceArray,
GcRoots,
GcRootInfo,
ArrayIndex {
base: Box<Attr>,
index: Box<Expr>,
},
ArraySlice {
base: Box<Attr>,
start: Option<Box<Expr>>,
end: Option<Box<Expr>>,
},
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum Expr {
Attr(Attr),
Lit(Value),
Binary {
op: ArithOp,
lhs: Box<Expr>,
rhs: Box<Expr>,
},
Unary {
op: UnaryOp,
arg: Box<Expr>,
},
Method {
receiver: Box<Expr>,
name: String,
args: Vec<Expr>,
},
Aggregate {
func: AggFunc,
arg: Box<SelectItem>,
},
Case {
branches: Vec<(Predicate, Expr)>,
else_: Option<Box<Expr>>,
},
Coalesce(Vec<Expr>),
NullIf {
lhs: Box<Expr>,
rhs: Box<Expr>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum ArithOp {
Add,
Sub,
Mul,
Div,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum UnaryOp {
Neg,
Pos,
}
impl Expr {
pub fn as_attr(&self) -> Option<&Attr> {
match self {
Expr::Attr(a) => Some(a),
_ => None,
}
}
pub fn as_lit(&self) -> Option<&Value> {
match self {
Expr::Lit(v) => Some(v),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum RefRole {
PredicateCritical,
ProjectionOnly,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub struct ClassSpec {
pub instanceof: bool,
pub class_name: String,
pub is_regex: bool,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum FromSource {
Class(ClassSpec),
Subquery(Box<Query>),
Object(u64),
}
impl FromSource {
pub fn class_name(&self) -> &str {
match self {
FromSource::Class(c) => &c.class_name,
FromSource::Subquery(_) => "",
FromSource::Object(_) => "",
}
}
pub fn class_spec(&self) -> Option<&ClassSpec> {
match self {
FromSource::Class(c) => Some(c),
FromSource::Subquery(_) => None,
FromSource::Object(_) => None,
}
}
pub fn instanceof(&self) -> bool {
matches!(self, FromSource::Class(c) if c.instanceof)
}
pub fn as_subquery(&self) -> Option<&Query> {
match self {
FromSource::Subquery(q) => Some(q),
FromSource::Class(_) => None,
FromSource::Object(_) => None,
}
}
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum Predicate {
And(Box<Predicate>, Box<Predicate>),
Or(Box<Predicate>, Box<Predicate>),
Not(Box<Predicate>),
Compare {
lhs: Expr,
op: CompareOp,
rhs: Expr,
},
InstanceOf(String),
InSubquery {
lhs: Attr,
inner: Box<Query>,
},
Exists {
inner: Box<Query>,
negated: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
pub enum CompareOp {
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Like,
NotLike,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub enum Value {
Int(i64),
Float(f64),
Str(String),
Bool(bool),
Null,
}