Add support for FETCH cluases in SQL RETURN statements

Closes #1323
This commit is contained in:
Tobie Morgan Hitchcock 2022-10-16 23:12:24 +01:00
parent f0bb81b809
commit 072bbdebdb

View file

@ -4,15 +4,19 @@ use crate::dbs::Transaction;
use crate::err::Error; use crate::err::Error;
use crate::sql::comment::shouldbespace; use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult; use crate::sql::error::IResult;
use crate::sql::fetch::{fetch, Fetchs};
use crate::sql::value::{value, Value}; use crate::sql::value::{value, Value};
use derive::Store; use derive::Store;
use nom::bytes::complete::tag_no_case; use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
pub struct OutputStatement { pub struct OutputStatement {
pub what: Value, pub what: Value,
pub fetch: Option<Fetchs>,
} }
impl OutputStatement { impl OutputStatement {
@ -30,24 +34,38 @@ impl OutputStatement {
// Ensure futures are processed // Ensure futures are processed
let opt = &opt.futures(true); let opt = &opt.futures(true);
// Process the output value // Process the output value
self.what.compute(ctx, opt, txn, doc).await let mut val = self.what.compute(ctx, opt, txn, doc).await?;
// Fetch any
if let Some(fetchs) = &self.fetch {
for fetch in fetchs.iter() {
val.fetch(ctx, opt, txn, fetch).await?;
}
}
//
Ok(val)
} }
} }
impl fmt::Display for OutputStatement { impl fmt::Display for OutputStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RETURN {}", self.what) write!(f, "RETURN {}", self.what)?;
if let Some(ref v) = self.fetch {
write!(f, " {}", v)?
}
Ok(())
} }
} }
pub fn output(i: &str) -> IResult<&str, OutputStatement> { pub fn output(i: &str) -> IResult<&str, OutputStatement> {
let (i, _) = tag_no_case("RETURN")(i)?; let (i, _) = tag_no_case("RETURN")(i)?;
let (i, _) = shouldbespace(i)?; let (i, _) = shouldbespace(i)?;
let (i, v) = value(i)?; let (i, what) = value(i)?;
let (i, fetch) = opt(preceded(shouldbespace, fetch))(i)?;
Ok(( Ok((
i, i,
OutputStatement { OutputStatement {
what: v, what,
fetch,
}, },
)) ))
} }