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));
  3. y.toEdgeQL();
  4. // WITH x := 3
  5. // SELECT x ^ 3
  6. const result = await y.run(client);
  7. // => 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. });
  11. /*
  12. with
  13. robert := (insert Person { name := "Robert Pattinson"}),
  14. colin := (insert Person { name := "Colin Farrell"}),
  15. insert Movie {
  16. title := "The Batman",
  17. actors := {robert, colin}
  18. }
  19. */

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. })
  12. /*
  13. insert Movie {
  14. title := "The Batman",
  15. actors := (
  16. with
  17. robert := (insert Person { name := "Robert Pattinson"}),
  18. colin := (insert Person { name := "Colin Farrell"})
  19. select {robert, colin}
  20. )
  21. }
  22. */

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);
  3. const query = e.select(e.op(a, '*', b))
  4. // WITH
  5. // a := {1, 2, 3},
  6. // b := a
  7. // SELECT a + b
  8. const result = await query.run(client);
  9. // => [1, 2, 3, 2, 4, 6, 3, 6, 9]