With Blocks
During the query rendering step, the number of occurrences of each expression are tracked. If an expression occurs more than once it is automatically extracted into a with block.
1. const x = e.int64(3);
2. const y = e.select(e.op(x, '^', x));
4. y.toEdgeQL();
5. // WITH x := 3
6. // SELECT x ^ 3
8. const result = await y.run(client);
9. // => 27
This hold for expressions of arbitrary complexity.
1. const robert = e.insert(e.Person, {
2. name: "Robert Pattinson"
3. });
4. const colin = e.insert(e.Person, {
5. name: "Colin Farrell"
6. });
7. const newMovie = e.insert(e.Movie, {
8. title: "The Batman",
9. actors: e.set(colin, robert)
10. });
12. /*
13. with
14. robert := (insert Person { name := "Robert Pattinson"}),
15. colin := (insert Person { name := "Colin Farrell"}),
16. insert Movie {
17. title := "The Batman",
18. actors := {robert, colin}
19. }
20. */
Note that robert and colin were pulled out into a top-level with block. To force these variables to occur in an internal with block, you can short-circuit this logic with e.with.
1. const robert = e.insert(e.Person, {
2. name: "Robert Pattinson"
3. });
4. const colin = e.insert(e.Person, {
5. name: "Colin Farrell"
6. });
7. const newMovie = e.insert(e.Movie, {
8. actors: e.with([robert, colin], // list "dependencies"
9. e.set(robert, colin)
10. )
11. })
13. /*
14. insert Movie {
15. title := "The Batman",
16. actors := (
17. with
18. robert := (insert Person { name := "Robert Pattinson"}),
19. colin := (insert Person { name := "Colin Farrell"})
20. select {robert, colin}
21. )
22. }
23. */
It’s an error to pass an expression into multiple e.withs, or use an expression passed to e.with outside of that block.
To explicitly create a detached “alias” of another expression, use e.alias.
1. const a = e.set(1, 2, 3);
2. const b = e.alias(a);
4. const query = e.select(e.op(a, '*', b))
5. // WITH
6. // a := {1, 2, 3},
7. // b := a
8. // SELECT a + b
10. const result = await query.run(client);
11. // => [1, 2, 3, 2, 4, 6, 3, 6, 9]
