use mz_expr::MirRelationExpr;
use crate::attribute::{Attribute, DerivedAttributes, DerivedAttributesBuilder};
#[derive(Default)]
#[allow(missing_debug_implementations)]
pub struct SubtreeSize {
pub results: Vec<usize>,
}
impl Attribute for SubtreeSize {
type Value = usize;
fn derive(&mut self, expr: &MirRelationExpr, _deps: &DerivedAttributes) {
use MirRelationExpr::*;
let n = self.results.len();
match expr {
Constant { .. } => {
self.results.push(1);
}
Get { .. } => {
self.results.push(1);
}
Let {
value: _, body: _, ..
} => {
let body = self.results[n - 1];
let value = self.results[n - 1 - body];
self.results.push(body + value + 1);
}
LetRec { values, .. } => {
let body = self.results[n - 1];
let mut total = body;
for _ in 0..values.len() {
total += self.results[n - 1 - total];
}
self.results.push(total + 1);
}
Project { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Map { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
FlatMap { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Filter { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Join { inputs, .. } => {
let mut offset = 1;
for _ in 0..inputs.len() {
offset += &self.results[n - offset];
}
self.results.push(offset);
}
Reduce { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
TopK { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Negate { input: _ } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Threshold { input: _ } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
Union { base: _, inputs } => {
let mut offset = 1;
for _ in 0..inputs.len() {
offset += &self.results[n - offset];
}
offset += &self.results[n - offset]; self.results.push(offset);
}
ArrangeBy { input: _, .. } => {
let input = self.results[n - 1];
self.results.push(input + 1);
}
}
}
fn add_dependencies(_builder: &mut DerivedAttributesBuilder)
where
Self: Sized,
{
}
fn get_results(&self) -> &Vec<Self::Value> {
&self.results
}
fn get_results_mut(&mut self) -> &mut Vec<Self::Value> {
&mut self.results
}
fn take(self) -> Vec<Self::Value> {
self.results
}
}