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

Bytes

bytes

Arrays

array<x>

Tuples

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

JSON

json

Strings

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

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

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

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

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

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

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

Indexing and slicing

str[i] str[from:to]

Concatenation

str ++ str

Utilities

len()

Transformation functions

str_split() str_lower() str_upper() str_title() str_pad_start() str_pad_end() str_trim() str_trim_start() str_trim_end() str_repeat()

Comparison operators

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

Search

contains() find()

Pattern matching and regexes

str like pattern str ilike pattern re_match() re_match_all() re_replace() re_test()

Booleans

The bool type represents a true/false value.

  1. db>
  1. select true;
  1. {true}
  1. db>
  1. select false;
  1. {false}

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

Comparison operators

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

Logical operators

or and not

Aggregation

all() any()

Numbers

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.

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

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

Comparison operators

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

Arithmetic

+ - - * / / % ^

Statistics

sum() min() max() math::mean() math::stddev() math::stddev_pop() math::var() math::var_pop()

Math

round() math::abs() math::ceil() math::floor() math::ln() math::lg() math::log()

Random number

random()

UUID

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

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

Generate a random UUID.

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

Enums

Enum types must be declared in your schema.

  1. 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:

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

Dates and times

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.

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

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

Comparison operators

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

Arithmetic

dt + dt dt - dt

String parsing

to_datetime() cal::to_local_datetime() cal::to_local_date() cal::to_local_time()

Component extraction

datetime_get() cal::time_get() cal::date_get()

Truncation

datetime_truncate()

System timestamps

datetime_current() datetime_of_transaction() datetime_of_statement()

Durations

EdgeDB’s typesystem contains three duration types.

duration

Exact duration

cal::relative_duration

Duration in relative units

cal::date_duration

Duration in months and days only

Exact durations

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.

  1. db>
  1. select <duration>'45.6 seconds';
  1. {<duration>'0:00:45.6'}
  1. db>
  1. select <duration>'-15 microseconds';
  1. {<duration>'-0:00:00.000015'}
  1. db>
  1. select <duration>'5 hours 4 minutes 3 seconds';
  1. {<duration>'5:04:03'}
  1. db>
  1. select <duration>'8760 hours'; # about a year
  1. {<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.

Relative durations

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:

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

Date durations

New

This type is only available in EdgeDB 2.0 or later.

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.

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

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

Comparison operators

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

Arithmetic

dt + dt dt - dt

Duration string parsing

to_duration() cal::to_relative_duration() cal::to_date_duration()

Component extraction

duration_get()

Conversion

duration_truncate() cal::duration_normalize_hours() cal::duration_normalize_days()

Ranges

New

This type is only available in EdgeDB 2.0 or later.

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.

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

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

  1. db>
  1. select range(1, 1);
  1. {range({}, empty := true)}
  1. db>
  1. select range(4, <int64>{});
  1. {range(4, {})}
  1. db>
  1. select range(<int64>{}, 4);
  1. {range({}, 4)}
  1. db>
  1. select range(<int64>{}, <int64>{});
  1. {range({}, {})}

To compute the set of concrete values defined by a range literal, use range_unpack.

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

Bytes

The bytes type represents raw binary data.

  1. db>
  1. select b'bina\\x01ry';
  1. {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.

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

Arrays

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

  1. db>
  1. select [1, 2, 3];
  1. {[1, 2, 3]}
  1. db>
  1. select ['hello', 'world'];
  1. {['hello', 'world']}
  1. db>
  1. select [(1, 2), (100, 200)];
  1. {[(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.

Tuples

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, tuples, and object types.

  1. db>
  1. select ('Apple', 7, true);
  1. {('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.

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

Indexing tuples

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.

  1. db>
  1. select (1, 3.14, 'red').0;
  1. {1}
  1. db>
  1. select (1, 3.14, 'red').2;
  1. {'red'}
  1. db>
  1. select (name := 'george', age := 12).name;
  1. {('george')}
  1. db>
  1. select (name := 'george', age := 12).0;
  1. {('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.

JSON

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.

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

JSON values support indexing operators. The resulting value is a json.

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

EdgeQL supports a set of functions and operators on json values. Refer to the Standard Library > JSON or click an item below for details 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()