Prevent subqueries from being executed multiple times (#4051)

This commit is contained in:
Tobie Morgan Hitchcock 2024-05-16 16:51:09 +01:00 committed by GitHub
parent 8077c15f41
commit 2219388802
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 65 additions and 12 deletions

View file

@ -43,18 +43,21 @@ impl Data {
txn: &Transaction,
) -> Result<Option<Value>, Error> {
match self {
Self::MergeExpression(v) => {
// This MERGE expression has an 'id' field
Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some())
}
Self::ReplaceExpression(v) => {
// This REPLACE expression has an 'id' field
Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some())
}
Self::ContentExpression(v) => {
// This CONTENT expression has an 'id' field
Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some())
}
Self::MergeExpression(v) => match v {
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
Value::Object(_) => Ok(v.rid().some()),
_ => Ok(None),
},
Self::ReplaceExpression(v) => match v {
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
Value::Object(_) => Ok(v.rid().some()),
_ => Ok(None),
},
Self::ContentExpression(v) => match v {
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
Value::Object(_) => Ok(v.rid().some()),
_ => Ok(None),
},
Self::SetExpression(v) => match v.iter().find(|f| f.0.is_id()) {
Some((_, _, v)) => {
// This SET expression has an 'id' field

View file

@ -397,6 +397,56 @@ async fn create_with_unique_index_on_two_fields() -> Result<(), Error> {
Ok(())
}
#[tokio::test]
async fn create_with_subquery_execution() -> Result<(), Error> {
let sql = "
CREATE person:test CONTENT {
address: (CREATE ONLY address CONTENT {
id: 'test', city: 'London'
})
};
SELECT * FROM person, address;
";
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 2);
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
{
address: {
city: 'London',
id: address:test
},
id: person:test
}
]",
);
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
{
address: {
city: 'London',
id: address:test
},
id: person:test
},
{
city: 'London',
id: address:test
}
]",
);
assert_eq!(tmp, val);
//
Ok(())
}
//
// Permissions
//