Search
ctrl/
Ask AI
Light
Dark
System

Literals

EdgeQL is inextricably tied to EdgeDB’s rigorous type system. Below is an overview of how to declare a literal value of each primitive type. Click a link in the left column to jump to the associated section.

String

str

Boolean

bool

Numbers

int16 int32 int64 float32 float64 bigint decimal

UUID

uuid

Enums

enum<X, Y, Z>

Dates and times

datetime duration cal::local_datetime cal::local_date cal::local_time cal::relative_duration

Durations

duration cal::relative_duration cal::date_duration

Ranges

range<x>

Bytes

bytes

Arrays

array<x>

Tuples

tuple<x, y, ...> or tuple<foo: x, bar: y, ...>

JSON

json

The str type is a variable-length string of Unicode characters. A string can be declared with either single or double quotes.

Copy
db> 
select 'i ❤️ edgedb';
{'i ❤️ edgedb'}
Copy
db> 
select "hello there!";
{'hello there!'}
Copy
db> 
select 'hello\nthere!';
{'hello
there!'}
Copy
db> 
... 
select 'hello
there!';
{'hello
there!'}
Copy
db> 
... 
select r'hello
there!'; # multiline
{'hello
there!'}

There is a special syntax for declaring “raw strings”. Raw strings treat the backslash \ as a literal character instead of an escape character.

Copy
db> 
select r'hello\nthere'; # raw string
{r'hello\\nthere'}
Copy
db> 
... 
... 
select $$one
two
three$$; # multiline raw string
{'one
two
three'}
Copy
db> 
... 
select $label$You can add an interstitial label
if you need to use "$$" in your string.$label$;
{
  'You can add an interstital label
  if you need to use "$$" in your string.',
}

EdgeQL contains a set of built-in functions and operators for searching, comparing, and manipulating strings.

Copy
db> 
select 'hellothere'[5:10];
{'there'}
Copy
db> 
select 'hello' ++ 'there';
{'hellothere'}
Copy
db> 
select len('hellothere');
{10}
Copy
db> 
select str_trim('  hello there  ');
{'hello there'}
Copy
db> 
select str_split('hello there', ' ');
{['hello', 'there']}

For a complete reference on strings, see Standard Library > String or click an item below.

The bool type represents a true/false value.

Copy
db> 
select true;
{true}
Copy
db> 
select false;
{false}

EdgeDB provides a set of operators that operate on boolean values.

Comparison operators

= != ?= ?!= < > <= >=

Logical operators

or and not

Aggregation

all() any()

There are several numerical types in EdgeDB’s type system.

int16

16-bit integer

int32

32-bit integer

int64

64-bit integer

float32

32-bit floating point number

float64

64-bit floating point number

bigint

Arbitrary precision integer.

decimal

Arbitrary precision number.

Number literals that do not contain a decimal are interpreted as int64. Numbers containing decimals are interpreted as float64. The n suffix designates a number with arbitrary precision: either bigint or decimal.

Syntax

Inferred type

select 3;

int64

select 3.14;

float64

select 314e-2;

float64

select 42n;

bigint

select 42.0n;

decimal

select 42e+100n;

decimal

To declare an int16, int32, or float32, you must provide an explicit type cast. For details on type casting, see Casting.

Syntax

Type

select <int16>1234;

int16

select <int32>123456;

int32

select <float32>123.456;

float32

EdgeQL includes a full set of arithmetic and comparison operators. Parentheses can be used to indicate the order-of-operations or visually group subexpressions; this is true across all EdgeQL queries.

Copy
db> 
select 5 > 2;
{true}
Copy
db> 
select 2 + 2;
{4}
Copy
db> 
select 2 ^ 10;
{1024}
Copy
db> 
select (1 + 1) * 2 / (3 + 8);
{0.36363636363636365}

EdgeQL provides a comprehensive set of built-in functions and operators on numerical data.

The uuid type is commonly used to represent object identifiers. UUID literal must be explicitly cast from a string value matching the UUID specification.

Copy
db> 
select <uuid>'a5ea6360-75bd-4c20-b69c-8f317b0d2857';
{a5ea6360-75bd-4c20-b69c-8f317b0d2857}

Generate a random UUID.

Copy
db> 
select uuid_generate_v1mc();
{b4d94e6c-3845-11ec-b0f4-93e867a589e7}

Enum types must be declared in your schema.

Copy
scalar type Color extending enum<Red, Green, Blue>;

Once declared, an enum literal can be declared with dot notation, or by casting an appropriate string literal:

Copy
db> 
select Color.Red;
{Red}
Copy
db> 
select <Color>"Red";
{Red}

EdgeDB’s typesystem contains several temporal types.

datetime

Timezone-aware point in time

cal::local_datetime

Date and time w/o timezone

cal::local_date

Date type

cal::local_time

Time type

All temporal literals are declared by casting an appropriately formatted string.

Copy
db> 
select <datetime>'1999-03-31T15:17:00Z';
{<datetime>'1999-03-31T15:17:00Z'}
Copy
db> 
select <datetime>'1999-03-31T17:17:00+02';
{<datetime>'1999-03-31T15:17:00Z'}
Copy
db> 
select <cal::local_datetime>'1999-03-31T15:17:00';
{<cal::local_datetime>'1999-03-31T15:17:00'}
Copy
db> 
select <cal::local_date>'1999-03-31';
{<cal::local_date>'1999-03-31'}
Copy
db> 
select <cal::local_time>'15:17:00';
{<cal::local_time>'15:17:00'}

EdgeQL supports a set of functions and operators on datetime types.

EdgeDB’s type system contains three duration types.

duration

Exact duration

cal::relative_duration

Duration in relative units

cal::date_duration

Duration in months and days only

The duration type represents exact durations that can be represented by some fixed number of microseconds. It can be negative and it supports units of microseconds, milliseconds, seconds, minutes, and hours.

Copy
db> 
select <duration>'45.6 seconds';
{<duration>'0:00:45.6'}
Copy
db> 
select <duration>'-15 microseconds';
{<duration>'-0:00:00.000015'}
Copy
db> 
select <duration>'5 hours 4 minutes 3 seconds';
{<duration>'5:04:03'}
Copy
db> 
select <duration>'8760 hours'; # about a year
{<duration>'8760:00:00'}

All temporal units beyond hour no longer correspond to a fixed duration of time; the length of a day/month/year/etc changes based on daylight savings time, the month in question, leap years, etc.

By contrast, the cal::relative_duration type represents a “calendar” duration, like 1 month. Because months have different number of days, 1 month doesn’t correspond to a fixed number of milliseconds, but it’s often a useful quantity to represent recurring events, postponements, etc.

The cal::relative_duration type supports the same units as duration, plus days, weeks, months, years, decades, centuries, and millennia.

To declare relative duration literals:

Copy
db> 
select <cal::relative_duration>'15 milliseconds';
{<cal::relative_duration>'PT.015S'}
Copy
db> 
select <cal::relative_duration>'2 months 3 weeks 45 minutes';
{<cal::relative_duration>'P2M21DT45M'}
Copy
db> 
select <cal::relative_duration>'-7 millennia';
{<cal::relative_duration>'P-7000Y'}

The cal::date_duration represents spans consisting of some number of months and days. This type is primarily intended to simplify logic involving cal::local_date values.

Copy
db> 
select <cal::date_duration>'5 days';
{<cal::date_duration>'P5D'}
Copy
db> 
select <cal::local_date>'2022-06-25' + <cal::date_duration>'5 days';
{<cal::local_date>'2022-06-30'}
Copy
db> 
select <cal::local_date>'2022-06-30' - <cal::local_date>'2022-06-25';
{<cal::date_duration>'P5D'}

EdgeQL supports a set of functions and operators on duration types.

Ranges represent a range of orderable scalar values. A range comprises a lower bound, upper bound, and two boolean flags indicating whether each bound is inclusive.

Create a range literal with the range constructor function.

Copy
db> 
select range(1, 10);
{range(1, 10, inc_lower := true, inc_upper := false)}
Copy
db> 
select range(2.2, 3.3);
{range(2.2, 3.3, inc_lower := true, inc_upper := false)}

Ranges can be empty, when the upper and lower bounds are equal.

Copy
db> 
select range(1, 1);
{range({}, empty := true)}

Ranges can be unbounded. An empty set is used to indicate the lack of a particular upper or lower bound.

Copy
db> 
select range(4, <int64>{});
{range(4, {})}
Copy
db> 
select range(<int64>{}, 4);
{range({}, 4)}
Copy
db> 
select range(<int64>{}, <int64>{});
{range({}, {})}

To compute the set of concrete values defined by a range literal, use range_unpack. An empty range will unpack to the empty set. Unbounded ranges cannot be unpacked.

Copy
db> 
select range_unpack(range(0, 10));
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Copy
db> 
select range_unpack(range(1, 1));
{}
Copy
db> 
select range_unpack(range(0, <int64>{}));
edgedb error: InvalidValueError: cannot unpack an unbounded range

The bytes type represents raw binary data.

Copy
db> 
select b'bina\\x01ry';
{b'bina\\x01ry'}

There is a special syntax for declaring “raw byte strings”. Raw byte strings treat the backslash \ as a literal character instead of an escape character.

Copy
db> 
select rb'hello\nthere';
{b'hello\\nthere'}
Copy
db> 
select br'\';
{b'\\'}

An array is an ordered collection of values of the same type. For example:

Copy
db> 
select [1, 2, 3];
{[1, 2, 3]}
Copy
db> 
select ['hello', 'world'];
{['hello', 'world']}
Copy
db> 
select [(1, 2), (100, 200)];
{[(1, 2), (100, 200)]}

EdgeQL provides a set of functions and operators on arrays.

Indexing and slicing

array[i] array[from:to] array_get()

Concatenation

array ++ array

Comparison operators

= != ?= ?!= < > <= >=

Utilities

len() array_join()

Search

contains() find()

Conversion to/from sets

array_agg() array_unpack()

See Standard Library > Array for a complete reference on array data types.

A tuple is fixed-length, ordered collection of values, each of which may have a different type. The elements of a tuple can be of any type, including scalars, arrays, other tuples, and object types.

Copy
db> 
select ('Apple', 7, true);
{('Apple', 7, true)}

Optionally, you can assign a key to each element of a tuple. These are known as named tuples. You must assign keys to all or none of the elements; you can’t mix-and-match.

Copy
db> 
select (fruit := 'Apple', quantity := 3.14, fresh := true);
{(fruit := 'Apple', quantity := 3.14, fresh := true)}

Tuple elements can be accessed with dot notation. Under the hood, there’s no difference between named and unnamed tuples. Named tuples support key-based and numerical indexing.

Copy
db> 
select (1, 3.14, 'red').0;
{1}
Copy
db> 
select (1, 3.14, 'red').2;
{'red'}
Copy
db> 
select (name := 'george', age := 12).name;
{('george')}
Copy
db> 
select (name := 'george', age := 12).0;
{('george')}

When you query an unnamed tuple using one of EdgeQL’s client libraries, its value is converted to a list/array. When you fetch a named tuple, it is converted to an object/dictionary/hashmap.

For a full reference on tuples, see Standard Library > Tuple.

The json scalar type is a stringified representation of structured data. JSON literals are declared by explicitly casting other values or passing a properly formatted JSON string into to_json(). Any type can be converted into JSON except bytes.

Copy
db> 
select <json>5;
{'5'}
Copy
db> 
select <json>"a string";
{'"a string"'}
Copy
db> 
select <json>["this", "is", "an", "array"];
{'["this", "is", "an", "array"]'}
Copy
db> 
select <json>("unnamed tuple", 2);
{'["unnamed tuple", 2]'}
Copy
db> 
select <json>(name := "named tuple", count := 2);
{'{
  "name": "named tuple",
  "count": 2
}'}
Copy
db> 
select to_json('{"a": 2, "b": 5}');
{'{"a": 2, "b": 5}'}

JSON values support indexing operators. The resulting value is also of type json.

Copy
db> 
select to_json('{"a": 2, "b": 5}')['a'];
{2}
Copy
db> 
select to_json('["a", "b", "c"]')[2];
{'"c"'}

EdgeQL supports a set of functions and operators on json values. Refer to the Standard Library > JSON or click an item below for detailed documentation.

Indexing

json[i] json[from:to] json[name] json_get()

Merging

json ++ json

Comparison operators

= != ?= ?!= < > <= >=

Conversion to/from strings

to_json() to_str()

Conversion to/from sets

json_array_unpack() json_object_unpack()

Introspection

json_typeof()