Skip to content

Commit 05a9e73

Browse files
Introduce Collector variant of Reducer to accomodate the unimplemented list reducer (#436)
## Product change and motivation It was placed under Stat, which it is not and caused confusion & crashes in core.
1 parent 63abd05 commit 05a9e73

4 files changed

Lines changed: 75 additions & 33 deletions

File tree

rust/common/token.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,20 @@ string_enum! { Annotation
157157
Values = "values",
158158
}
159159

160-
string_enum! { ReduceOperator
160+
string_enum! { ReduceOperatorCount
161161
Count = "count",
162+
}
163+
164+
string_enum! { ReduceOperatorStat
162165
Max = "max",
163166
Mean = "mean",
164167
Median = "median",
165168
Min = "min",
166169
Std = "std",
167170
Sum = "sum",
171+
}
172+
173+
string_enum! { ReduceOperatorCollect
168174
List = "list",
169175
}
170176

rust/parser/pipeline.rs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use super::{
1717
use crate::{
1818
common::{
1919
error::TypeQLError,
20-
token::{Order, ReduceOperator},
20+
token::{Order, ReduceOperatorCollect, ReduceOperatorStat},
2121
Spanned,
2222
},
2323
parser::define::function::visit_function_block,
@@ -28,7 +28,7 @@ use crate::{
2828
delete::{Deletable, DeletableKind},
2929
fetch::FetchSome,
3030
modifier::{Distinct, Limit, Offset, OrderedVariable, Require, Select, Sort},
31-
reduce::{Count, Reducer, Stat},
31+
reduce::{Collect, Count, Reducer, Stat},
3232
Delete, Fetch, Insert, Match, Operator, Put, Reduce, Stage, Update,
3333
},
3434
Preamble,
@@ -411,32 +411,41 @@ pub(crate) fn visit_reducer(node: Node<'_>) -> Reducer {
411411
let keyword = children.consume_any();
412412
match keyword.as_rule() {
413413
Rule::COUNT => Reducer::Count(Count::new(span, children.try_consume_expected(Rule::var).map(visit_var))),
414-
Rule::MAX => {
415-
Reducer::Stat(Stat::new(span, ReduceOperator::Max, visit_var(children.consume_expected(Rule::var))))
414+
Rule::reducer_stat => {
415+
let operator = visit_reducer_stat(keyword);
416+
Reducer::Stat(Stat::new(span, operator, visit_var(children.consume_expected(Rule::var))))
416417
}
417-
Rule::MIN => {
418-
Reducer::Stat(Stat::new(span, ReduceOperator::Min, visit_var(children.consume_expected(Rule::var))))
419-
}
420-
Rule::MEAN => {
421-
Reducer::Stat(Stat::new(span, ReduceOperator::Mean, visit_var(children.consume_expected(Rule::var))))
422-
}
423-
Rule::MEDIAN => {
424-
Reducer::Stat(Stat::new(span, ReduceOperator::Median, visit_var(children.consume_expected(Rule::var))))
425-
}
426-
Rule::STD => {
427-
Reducer::Stat(Stat::new(span, ReduceOperator::Std, visit_var(children.consume_expected(Rule::var))))
428-
}
429-
Rule::SUM => {
430-
Reducer::Stat(Stat::new(span, ReduceOperator::Sum, visit_var(children.consume_expected(Rule::var))))
431-
}
432-
Rule::LIST => {
433-
// TODO vvvv rename
434-
Reducer::Stat(Stat::new(span, ReduceOperator::List, visit_var(children.consume_expected(Rule::var))))
418+
Rule::reducer_collect => {
419+
let operator = visit_reducer_collect(keyword);
420+
Reducer::Collect(Collect::new(span, operator, visit_var(children.consume_expected(Rule::var))))
435421
}
436422
_ => unreachable!("{}", TypeQLError::IllegalGrammar { input: keyword.as_str().to_owned() }),
437423
}
438424
}
439425

426+
fn visit_reducer_stat(node: Node<'_>) -> ReduceOperatorStat {
427+
debug_assert_eq!(node.as_rule(), Rule::reducer_stat);
428+
let child = node.into_child();
429+
match child.as_rule() {
430+
Rule::MAX => ReduceOperatorStat::Max,
431+
Rule::MIN => ReduceOperatorStat::Min,
432+
Rule::MEAN => ReduceOperatorStat::Mean,
433+
Rule::MEDIAN => ReduceOperatorStat::Median,
434+
Rule::STD => ReduceOperatorStat::Std,
435+
Rule::SUM => ReduceOperatorStat::Sum,
436+
_ => unreachable!("{}", TypeQLError::IllegalGrammar { input: child.as_str().to_owned() }),
437+
}
438+
}
439+
440+
fn visit_reducer_collect(node: Node<'_>) -> ReduceOperatorCollect {
441+
debug_assert_eq!(node.as_rule(), Rule::reducer_collect);
442+
let child = node.into_child();
443+
match child.as_rule() {
444+
Rule::LIST => ReduceOperatorCollect::List,
445+
_ => unreachable!("{}", TypeQLError::IllegalGrammar { input: child.as_str().to_owned() }),
446+
}
447+
}
448+
440449
fn visit_operator_select(node: Node<'_>) -> Select {
441450
debug_assert_eq!(node.as_rule(), Rule::operator_select);
442451
let span = node.span();

rust/parser/typeql.pest

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,11 @@ reduce_assign = { ( reduce_assignment_var ~ ASSIGN ~ reducer ) }
5353

5454
reduce_assignment_var = { var_optional | var }
5555
reducer = { COUNT ~ ( PAREN_OPEN ~ var ~ PAREN_CLOSE )?
56-
| MAX ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
57-
| MIN ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
58-
| MEAN ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
59-
| MEDIAN ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
60-
| STD ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
61-
| SUM ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
62-
| LIST ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
56+
| reducer_stat ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
57+
| reducer_collect ~ PAREN_OPEN ~ var ~ PAREN_CLOSE
6358
}
59+
reducer_stat = { MAX | MIN | MEAN | MEDIAN | STD | SUM }
60+
reducer_collect = { LIST }
6461

6562
// QUERY PATTERNS ==============================================================
6663

rust/query/pipeline/stage/reduce.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ impl fmt::Display for ReduceAssign {
8282
pub enum Reducer {
8383
Count(Count),
8484
Stat(Stat),
85+
Collect(Collect),
8586
}
8687

8788
impl Pretty for Reducer {
8889
fn fmt(&self, indent_level: usize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8990
match self {
9091
Self::Count(inner) => Pretty::fmt(inner, indent_level, f),
9192
Self::Stat(inner) => Pretty::fmt(inner, indent_level, f),
93+
Self::Collect(inner) => Pretty::fmt(inner, indent_level, f),
9294
}
9395
}
9496
}
@@ -98,6 +100,7 @@ impl fmt::Display for Reducer {
98100
match self {
99101
Self::Count(inner) => fmt::Display::fmt(inner, f),
100102
Self::Stat(inner) => fmt::Display::fmt(inner, f),
103+
Self::Collect(inner) => fmt::Display::fmt(inner, f),
101104
}
102105
}
103106
}
@@ -124,7 +127,7 @@ impl Pretty for Count {}
124127

125128
impl fmt::Display for Count {
126129
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127-
write!(f, "{}", token::ReduceOperator::Count)?;
130+
write!(f, "{}", token::ReduceOperatorCount::Count)?;
128131
if let Some(variable) = &self.variable {
129132
write!(f, "({})", variable)?;
130133
}
@@ -135,12 +138,12 @@ impl fmt::Display for Count {
135138
#[derive(Debug, Clone, Eq, PartialEq)]
136139
pub struct Stat {
137140
pub span: Option<Span>,
138-
pub reduce_operator: token::ReduceOperator,
141+
pub reduce_operator: token::ReduceOperatorStat,
139142
pub variable: Variable,
140143
}
141144

142145
impl Stat {
143-
pub fn new(span: Option<Span>, aggregate: token::ReduceOperator, variable: Variable) -> Self {
146+
pub fn new(span: Option<Span>, aggregate: token::ReduceOperatorStat, variable: Variable) -> Self {
144147
Self { span, reduce_operator: aggregate, variable }
145148
}
146149
}
@@ -158,3 +161,30 @@ impl fmt::Display for Stat {
158161
write!(f, "{}({})", self.reduce_operator, self.variable)
159162
}
160163
}
164+
165+
#[derive(Debug, Clone, Eq, PartialEq)]
166+
pub struct Collect {
167+
pub span: Option<Span>,
168+
pub reduce_operator: token::ReduceOperatorCollect,
169+
pub variable: Variable,
170+
}
171+
172+
impl Collect {
173+
pub fn new(span: Option<Span>, aggregate: token::ReduceOperatorCollect, variable: Variable) -> Self {
174+
Self { span, reduce_operator: aggregate, variable }
175+
}
176+
}
177+
178+
impl Spanned for Collect {
179+
fn span(&self) -> Option<Span> {
180+
self.span
181+
}
182+
}
183+
184+
impl Pretty for Collect {}
185+
186+
impl fmt::Display for Collect {
187+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188+
write!(f, "{}({})", self.reduce_operator, self.variable)
189+
}
190+
}

0 commit comments

Comments
 (0)