Search
ctrl/
Ask AI
Light
Dark
System

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.

Copy
const x = e.int64(3);
const y = e.select(e.op(x, '^', x));

y.toEdgeQL();
// with x := 3
// select x ^ x

const result = await y.run(client);
// => 27

This hold for expressions of arbitrary complexity.

Copy
const robert = e.insert(e.Person, {
  name: "Robert Pattinson"
});
const colin = e.insert(e.Person, {
  name: "Colin Farrell"
});
const newMovie = e.insert(e.Movie, {
  title: "The Batman",
  actors: e.set(colin, robert)
});

/*
with
  robert := (insert Person {  name := "Robert Pattinson"}),
  colin := (insert Person {  name := "Colin Farrell"}),
insert Movie {
  title := "The Batman",
  actors := {robert, colin}
}
*/

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.

Copy
const robert = e.insert(e.Person, {
  name: "Robert Pattinson"
});
const colin = e.insert(e.Person, {
  name: "Colin Farrell"
});
const newMovie = e.insert(e.Movie, {
  actors: e.with([robert, colin], // list "dependencies"
    e.select(e.set(robert, colin))
  )
})

/*
insert Movie {
  title := "The Batman",
  actors := (
    with
      robert := (insert Person {  name := "Robert Pattinson"}),
      colin := (insert Person {  name := "Colin Farrell"})
    select {robert, colin}
  )
}
*/

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.

Copy
const a = e.set(1, 2, 3);
const b = e.alias(a);

const query = e.select(e.op(a, '*', b))
// WITH
//   a := {1, 2, 3},
//   b := a
// SELECT a + b

const result = await query.run(client);
// => [1, 2, 3, 2, 4, 6, 3, 6, 9]