Types​
The foundation of EdgeQL is Gel's rigorous type system. There is a set of EdgeQL operators and functions for changing, introspecting, and filtering by types.
Type expressions​
Type expressions are exactly what they sound like: EdgeQL expressions that
refer to a type. Most commonly, these are simply the names of established
types: str, int64, BlogPost, etc. Arrays and tuples have a
dedicated type syntax.
|
Type |
Syntax |
|
Array |
|
|
Tuple (unnamed) |
|
|
Tuple (named) |
|
For additional details on type syntax, see Schema > Primitive Types.
Type casting​
Type casting is used to convert primitive values into another type. Casts are indicated with angle brackets containing a type expression.
db>
select <str>10;{"10"}db>
select <bigint>10;{10n}db>
select <array<str>>[1, 2, 3];{['1', '2', '3']}db>
select <tuple<str, float64, bigint>>(1, 2, 3);{('1', 2, 3n)}Type casts are useful for declaring literals for types like datetime,
uuid, and int16 that don't have a dedicated syntax.
db>
select <datetime>'1999-03-31T15:17:00Z';{<datetime>'1999-03-31T15:17:00Z'}db>
select <int16>42;{42}db>
select <uuid>'89381587-705d-458f-b837-860822e1b219';{89381587-705d-458f-b837-860822e1b219}There are limits to what values can be cast to a certain type. In some cases
two types are entirely incompatible, like bool and int64; in other
cases, the source data must be in a particular format, like casting str to
datetime. For a comprehensive table of castability, see Standard
Library > Casts.
Type casts can only be used on primitive expressions, not object type expressions. Every object stored in the database is strongly and immutably typed; you can't simply convert an object to an object of a different type.
db>
select <BlogPost>10;QueryError: cannot cast 'std::int64' to 'default::BlogPost'
db>
select <int64>'asdf';InvalidValueError: invalid input syntax for type std::int64: "asdf"
db>
select <int16>100000000000000n;NumericOutOfRangeError: std::int16 out of range
You can cast a UUID into an object:
db>
select <Hero><uuid>'01d9cc22-b776-11ed-8bef-73f84c7e91e7';{default::Hero {id: 01d9cc22-b776-11ed-8bef-73f84c7e91e7}}If you try to cast a UUID that no object of the type has as its id
property, you'll get an error:
db>
select <Hero><uuid>'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';gel error: CardinalityViolationError: 'default::Hero' with id 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' does not exist
Type intersections​
All elements of a given set have the same type; however, in the context of
sets of objects, this type might be abstract and contain elements of
multiple concrete subtypes. For instance, a set of Media objects may
contain both Movie and TVShow objects.
db>
select Media;{
default::Movie {id: 9d2ce01c-35e8-11ec-acc3-83b1377efea0},
default::Movie {id: 3bfe4900-3743-11ec-90ee-cb73d2740820},
default::TVShow {id: b0e0dd0c-35e8-11ec-acc3-abf1752973be},
}We can use the type intersection operator to restrict the elements of a set by subtype.
db>
select Media[is Movie];{
default::Movie {id: 9d2ce01c-35e8-11ec-acc3-83b1377efea0},
default::Movie {id: 3bfe4900-3743-11ec-90ee-cb73d2740820},
}Logically, this computes the intersection of the Media and Movie sets;
since only Movie objects occur in both sets, this can be conceptualized as
a "filter" that removes all elements that aren't of type Movie.
Type checking​
The [is foo] "type intersection" syntax should not be confused with the
type checking operator is.
db>
select 5 is int64;{true}db>
select {3.14, 2.718} is not int64;{true, true}db>
select Media is Movie;{true, true, false}The typeof operator​
The type of any expression can be extracted with the typeof
operator. This can be used in any expression that expects a type.
db>
select <typeof 5>'100';{100}db>
select "tuna" is typeof "trout";{true}Introspection​
The entire type system of Gel is stored inside Gel. All types are
introspectable as instances of the schema::Type type. For a set of
introspection examples, see Guides > Introspection.