diff --git a/lib/src/doc/pluck.rs b/lib/src/doc/pluck.rs index 8cd32a17..226a2e2f 100644 --- a/lib/src/doc/pluck.rs +++ b/lib/src/doc/pluck.rs @@ -27,10 +27,12 @@ impl<'a> Document<'a> { Output::Diff => Ok(self.initial.diff(&self.current, Idiom::default()).into()), 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::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 { - 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(_) => { self.current.compute(ctx, opt, txn, Some(&self.current)).await } diff --git a/lib/src/sql/field.rs b/lib/src/sql/field.rs index 306661ed..a0cee1c5 100644 --- a/lib/src/sql/field.rs +++ b/lib/src/sql/field.rs @@ -66,6 +66,7 @@ impl Fields { opt: &Options, txn: &Transaction, doc: Option<&Value>, + group: bool, ) -> Result { // Ensure futures are run let opt = &opt.futures(true); @@ -80,6 +81,16 @@ impl Fields { match v { Field::All => (), 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 Value::Idiom(v) if v.is_multi_yield() => { // Store the different output yields here @@ -117,6 +128,16 @@ impl Fields { } }, 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 Value::Idiom(v) if v.is_multi_yield() => { // Store the different output yields here