Literals

The query builder provides a set of “helper functions” that convert JavaScript literals into expressions that can be used in queries. For the most part, these helper functions correspond to the name of the type.

Primitives

Primitive literal expressions are created using constructor functions that correspond to EdgeDB datatypes. Each expression below is accompanied by the EdgeQL it produces.

  1. e.str("asdf") // "asdf"
  2. e.int64(123) // 123
  3. e.float64(123.456) // 123.456
  4. e.bool(true) // true
  5. e.bigint(12345n) // 12345n
  6. e.decimal("1234.1234n") // 1234.1234n
  7. e.uuid("599236a4...") // <uuid>"599236a4..."
  8. e.bytes(Buffer.from('binary data'));
  9. // b'binary data'

Strings

String expressions have some special functionality: they support indexing and slicing, as in EdgeQL.

  1. const myString = e.str("hello world");
  2. myString[5]; // "hello world"[5]
  3. myString['2:5']; // "hello world"[2:5]
  4. myString[':5']; // "hello world"[:5]
  5. myString['2:']; // "hello world"[2:]

There are also equivalent .index and .slice methods that can accept integer expressions as arguments.

  1. const myString = e.str("hello world");
  2. const start = e.int64(2);
  3. const end = e.int64(5);
  4. myString.index(start); // "hello world"[2]
  5. myString.slice(start, end); // "hello world"[2:5]
  6. myString.slice(null, end); // "hello world"[:5]
  7. myString.slice(start, null); // "hello world"[2:]

Enums

Enum literals are available as properties defined on the enum type.

  1. e.Colors.green;
  2. // Colors.green;
  3. e.sys.VersionStage.beta;
  4. // sys::VersionStage.beta

Dates and times

To create an instance of datetime, pass a JavaScript Date object into e.datetime:

  1. e.datetime(new Date('1999-01-01'));
  2. // <datetime>'1999-01-01T00:00:00.000Z'

EdgeDB’s other temporal datatypes don’t have equivalents in the JavaScript type system: duration, cal::relative_duration, cal::date_duration, cal::local_date, cal::local_time, and cal::local_datetime,

To resolve this, each of these datatypes can be represented with an instance of a corresponding class, as defined in edgedb module. The driver uses these classes to represent these values in query results; they are documented on the Driver page.

e.duration

Duration()

e.cal.relative_duration

RelativeDuration()

e.cal.date_duration

DateDuration()

e.cal.local_date

LocalDate()

e.cal.local_time

LocalTime()

e.cal.local_datetime

LocalDateTime()

e.cal.local_datetime

LocalDateTime()

e.cal.local_datetime

LocalDateTime()

The code below demonstrates how to declare each kind of temporal literal, along with the equivalent EdgeQL.

  1. import * as edgedb from "edgedb";
  2. const myDuration = new edgedb.Duration(0, 0, 0, 0, 1, 2, 3);
  3. e.duration(myDuration);
  4. const myLocalDate = new edgedb.LocalDate(1776, 7, 4);
  5. e.cal.local_date(myLocalDate);
  6. const myLocalTime = new edgedb.LocalTime(13, 15, 0);
  7. e.cal.local_time(myLocalTime);
  8. const myLocalDateTime = new edgedb.LocalDateTime(1776, 7, 4, 13, 15, 0);
  9. e.cal.local_datetime(myLocalDateTime);

You can also declare these literals by casting an appropriately formatted str expression, as in EdgeQL. Casting is documented in more detail later in the docs.

  1. e.cast(e.duration, e.str('5 minutes'));
  2. // <std::duration>'5 minutes'
  3. e.cast(e.cal.local_datetime, e.str('1999-03-31T15:17:00'));
  4. // <cal::local_datetime>'1999-03-31T15:17:00'
  5. e.cast(e.cal.local_date, e.str('1999-03-31'));
  6. // <cal::local_date>'1999-03-31'
  7. e.cast(e.cal.local_time, e.str('15:17:00'));
  8. // <cal::local_time>'15:17:00'

JSON

JSON literals are created with the e.json function. You can pass in any EdgeDB-compatible data structure.

What does “EdgeDB-compatible” mean? It means any JavaScript data structure with an equivalent in EdgeDB: strings, number, booleans, bigints, Buffers, Dates, and instances of EdgeDB’s built-in classes: (LocalDate LocalTime, LocalDateTime, DateDuration, Duration, and RelativeDuration), and any array or object of these types. Other JavaScript data structures like symbols, instances of custom classes, sets, maps, and typed arrays are not supported.

  1. const query = e.json({ name: "Billie" })
  2. // to_json('{"name": "Billie"}')
  3. const data = e.json({
  4. name: "Billie",
  5. numbers: [1,2,3],
  6. nested: { foo: "bar"},
  7. duration: new edgedb.Duration(1, 3, 3)
  8. })

JSON expressions support indexing, as in EdgeQL. The returned expression also has a json type.

  1. const query = e.json({ numbers: [0,1,2] });
  2. query.toEdgeQL(); // to_json((numbers := [0,1,2]))
  3. query.numbers[0].toEdgeQL();
  4. // to_json('{"numbers":[0,1,2]}')['numbers'][0]

The inferred type associated with a json expression is unknown.

  1. const result = await query.run(client)
  2. // unknown

Arrays

Declare array expressions by passing an array of expressions into e.array.

  1. e.array([e.str("a"), e.str("b"), e.str("b")]);
  2. // ["a", "b", "c"]

EdgeQL semantics are enforced by TypeScript, so arrays can’t contain elements with incompatible types.

  1. e.array([e.int64(5), e.str("foo")]);
  2. // TypeError!

For convenience, the e.array can also accept arrays of plain JavaScript data as well.

  1. e.array(['a', 'b', 'c']);
  2. // ['a', 'b', 'c']
  3. // you can intermixing expressions and plain data
  4. e.array([1, 2, e.int64(3)]);
  5. // [1, 2, 3]

Array expressions also support indexing and slicing operations.

  1. const myArray = e.array(['a', 'b', 'c', 'd', 'e']);
  2. // ['a', 'b', 'c', 'd', 'e']
  3. myArray[1];
  4. // ['a', 'b', 'c', 'd', 'e'][1]
  5. myArray['1:3'];
  6. // ['a', 'b', 'c', 'd', 'e'][1:3]

There are also equivalent .index and .slice methods that can accept other expressions as arguments.

  1. const start = e.int64(1);
  2. const end = e.int64(3);
  3. myArray.index(start);
  4. // ['a', 'b', 'c', 'd', 'e'][1]
  5. myArray.slice(start, end);
  6. // ['a', 'b', 'c', 'd', 'e'][1:3]

Tuples

Declare tuples with e.tuple. Pass in an array to declare a “regular” (unnamed) tuple; pass in an object to declare a named tuple.

  1. e.tuple([e.str("Peter Parker"), e.int64(18)]);
  2. // ("Peter Parker", 18)
  3. e.tuple({
  4. name: e.str("Peter Parker"),
  5. age: e.int64(18)
  6. });
  7. // (name := "Peter Parker", age := 18)

Tuple expressions support indexing.

  1. // Unnamed tuples
  2. const spidey = e.tuple([
  3. e.str("Peter Parker"),
  4. e.int64(18)
  5. ]);
  6. spidey[0]; // => ("Peter Parker", 18)[0]
  7. // Named tuples
  8. const spidey = e.tuple({
  9. name: e.str("Peter Parker"),
  10. age: e.int64(18)
  11. });
  12. spidey.name;
  13. // (name := "Peter Parker", age := 18).name

Set literals

Declare sets with e.set.

  1. e.set(e.str("asdf"), e.str("qwer"));
  2. // {'asdf', 'qwer'}

As in EdgeQL, sets can’t contain elements with incompatible types. These semantics are enforced by TypeScript.

  1. e.set(e.int64(1234), e.str('sup'));
  2. // TypeError

Empty sets

To declare an empty set, cast an empty set to the desired type. As in EdgeQL, empty sets are not allowed without a cast.

  1. e.cast(e.int64, e.set());
  2. // <std::int64>{}

Range literals

As in EdgeQL, declare range literals with the built-in range function.

  1. const myRange = e.range(0, 8);
  2. myRange.toEdgeQL();
  3. // => std::range(0, 8);

Ranges can be created for all numerical types, as well as datetime, local_datetime, and local_date.

  1. e.range(e.decimal('100'), e.decimal('200'));
  2. e.range(Date.parse("1970-01-01"), Date.parse("2022-01-01"));
  3. e.range(new LocalDate(1970, 1, 1), new LocalDate(2022, 1, 1));

Supply named parameters as the first argument.

  1. e.range({inc_lower: true, inc_upper: true, empty: true}, 0, 8);
  2. // => std::range(0, 8, true, true);

JavaScript doesn’t have a native way to represent range values. Any range value returned from a query will be encoded as an instance of the Range() class, which is exported from the edgedb package.

  1. const query = e.range(0, 8);
  2. const result = await query.run(client);
  3. // => Range<number>;
  4. console.log(result.lower); // 0
  5. console.log(result.upper); // 8
  6. console.log(result.isEmpty); // false
  7. console.log(result.incLower); // true
  8. console.log(result.incUpper); // false