Ensure aggregate functions are computed in GROUP BY clauses
This commit is contained in:
parent
c9d9b041f7
commit
c9a5b66d9c
2 changed files with 25 additions and 2 deletions
|
@ -27,10 +27,12 @@ impl<'a> Document<'a> {
|
||||||
Output::Diff => Ok(self.initial.diff(&self.current, Idiom::default()).into()),
|
Output::Diff => Ok(self.initial.diff(&self.current, Idiom::default()).into()),
|
||||||
Output::After => self.current.compute(ctx, opt, txn, Some(&self.current)).await,
|
Output::After => self.current.compute(ctx, opt, txn, Some(&self.current)).await,
|
||||||
Output::Before => self.initial.compute(ctx, opt, txn, Some(&self.initial)).await,
|
Output::Before => self.initial.compute(ctx, opt, txn, Some(&self.initial)).await,
|
||||||
Output::Fields(v) => v.compute(ctx, opt, txn, Some(&self.current)).await,
|
Output::Fields(v) => v.compute(ctx, opt, txn, Some(&self.current), false).await,
|
||||||
},
|
},
|
||||||
None => match stm {
|
None => match stm {
|
||||||
Statement::Select(s) => s.expr.compute(ctx, opt, txn, Some(&self.current)).await,
|
Statement::Select(s) => {
|
||||||
|
s.expr.compute(ctx, opt, txn, Some(&self.current), s.group.is_some()).await
|
||||||
|
}
|
||||||
Statement::Create(_) => {
|
Statement::Create(_) => {
|
||||||
self.current.compute(ctx, opt, txn, Some(&self.current)).await
|
self.current.compute(ctx, opt, txn, Some(&self.current)).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ impl Fields {
|
||||||
opt: &Options,
|
opt: &Options,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
doc: Option<&Value>,
|
doc: Option<&Value>,
|
||||||
|
group: bool,
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
// Ensure futures are run
|
// Ensure futures are run
|
||||||
let opt = &opt.futures(true);
|
let opt = &opt.futures(true);
|
||||||
|
@ -80,6 +81,16 @@ impl Fields {
|
||||||
match v {
|
match v {
|
||||||
Field::All => (),
|
Field::All => (),
|
||||||
Field::Alone(v) => match v {
|
Field::Alone(v) => match v {
|
||||||
|
// This expression is a grouped aggregate function
|
||||||
|
Value::Function(f) if group && f.is_aggregate() => {
|
||||||
|
let x = match f.args().len() {
|
||||||
|
// If no function arguments, then compute the result
|
||||||
|
0 => f.compute(ctx, opt, txn, Some(doc)).await?,
|
||||||
|
// If arguments, then pass the first value through
|
||||||
|
_ => f.args()[0].compute(ctx, opt, txn, Some(doc)).await?,
|
||||||
|
};
|
||||||
|
out.set(ctx, opt, txn, v.to_idiom().as_ref(), x).await?;
|
||||||
|
}
|
||||||
// This expression is a multi-output graph traversal
|
// This expression is a multi-output graph traversal
|
||||||
Value::Idiom(v) if v.is_multi_yield() => {
|
Value::Idiom(v) if v.is_multi_yield() => {
|
||||||
// Store the different output yields here
|
// Store the different output yields here
|
||||||
|
@ -117,6 +128,16 @@ impl Fields {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Field::Alias(v, i) => match v {
|
Field::Alias(v, i) => match v {
|
||||||
|
// This expression is a grouped aggregate function
|
||||||
|
Value::Function(f) if group && f.is_aggregate() => {
|
||||||
|
let x = match f.args().len() {
|
||||||
|
// If no function arguments, then compute the result
|
||||||
|
0 => f.compute(ctx, opt, txn, Some(doc)).await?,
|
||||||
|
// If arguments, then pass the first value through
|
||||||
|
_ => f.args()[0].compute(ctx, opt, txn, Some(doc)).await?,
|
||||||
|
};
|
||||||
|
out.set(ctx, opt, txn, v.to_idiom().as_ref(), x).await?;
|
||||||
|
}
|
||||||
// This expression is a multi-output graph traversal
|
// This expression is a multi-output graph traversal
|
||||||
Value::Idiom(v) if v.is_multi_yield() => {
|
Value::Idiom(v) if v.is_multi_yield() => {
|
||||||
// Store the different output yields here
|
// Store the different output yields here
|
||||||
|
|
Loading…
Reference in a new issue