Set Functions and Operators​

distinct set

Return a set without repeating any elements.

anytype in set

Test the membership of an element in a set.

set union set

Merge two sets.

exists set

Test whether a set is not empty.

set if bool else set

Conditionally provide one or the other result.

optional anytype ?? set

Coalesce.

detached

Detaches the input set reference from the current scope.

anytype [is type]

Filter the set based on type.

assert_distinct()

Check that the input set contains only unique elements, i.e a proper set.

assert_single()

Check that the input set contains no more than one element.

assert_exists()

Check that the input set contains at least one element.

count()

Return the number of elements in a set.

array_agg()

Return an array made from all of the input set elements.

sum()

Return the sum of the set of numbers.

all()

Generalized boolean and applied to the set of values.

any()

Generalized boolean or applied to the set of values.

enumerate()

Return a set of tuples of the form (index, element).

min()

Return the smallest value of the input set.

max()

Return the greatest value of the input set.

math::mean()

Return the arithmetic mean of the input set.

math::stddev()

Return the sample standard deviation of the input set.

math::stddev_pop()

Return the population standard deviation of the input set.

math::var()

Return the sample variance of the input set.

math::var_pop()

Return the population variance of the input set.

operator

distinct set

Set - 图1

distinct set of anytype -> set of anytype

Return a set without repeating any elements.

distinct is a set operator that returns a new set where no member is equal to any other member.

  1. select distinct {1, 2, 2, 3};
  1. {1, 2, 3}

operator

anytype in set

Set - 图2

anytype in set of anytype -> boolanytype not in set of anytype -> bool

Test the membership of an element in a set.

Set membership operators in and not in that test for each element of A whether it is present in B.

  1. select 1 in {1, 3, 5};
  1. {true}
  1. select 'Alice' in User.name;
  1. {true}
  1. select {1, 2} in {1, 3, 5};
  1. {true, false}

This operator can also be used to implement set intersection:

  1. with
  2. A := {1, 2, 3, 4},
  3. B := {2, 4, 6}
  4. select A filter A in B;
  1. {2, 4}

operator

set union set

Set - 图3

set of anytype union set of anytype -> set of anytype

Merge two sets.

Since EdgeDB sets are formally multisets, union is a multiset sum, so effectively it merges two multisets keeping all of their members.

For example, applying union to {1, 2, 2} and {2}, results in {1, 2, 2, 2}.

If you need a distinct union, wrap it with distinct.

operator

set if bool else set

Set - 图4

set of anytype if bool else set of anytype -> set of anytype

Conditionally provide one or the other result.

  1. left_expr if condition else right_expr

If condition is true, then the value of the if..else expression is the value of left_expr; if condition is false, the result is the value of right_expr.

  1. select 'hello' if 2 * 2 = 4 else 'bye';
  1. {'hello'}

if..else expressions can be chained when checking multiple conditions is necessary:

  1. with color := 'yellow'
  2. select 'Apple' if color = 'red' else
  3. 'Banana' if color = 'yellow' else
  4. 'Orange' if color = 'orange' else
  5. 'Other';
  1. {'Banana'}

operator

optional anytype ?? set

Set - 图5

optional anytype ?? set of anytype -> set of anytype

Coalesce.

Evaluate to A for non-empty A, otherwise evaluate to B.

A typical use case of the coalescing operator is to provide default values for optional properties.

  1. # Get a set of tuples (<issue name>, <priority>)
  2. # for all issues.
  3. select (Issue.name, Issue.priority.name ?? 'n/a');

Without the coalescing operator the above query would skip any Issue without priority.

operator

detached

Set - 图6

detached set of anytype -> set of anytype

Detaches the input set reference from the current scope.

A detached expression allows referring to some set as if it were defined in the top-level with block. detached expressions ignore all current scopes in which they are nested. This makes it possible to write queries that reference the same set reference in multiple places.

  1. update User
  2. filter .name = 'Dave'
  3. set {
  4. friends := (select detached User filter .name = 'Alice'),
  5. coworkers := (select detached User filter .name = 'Bob')
  6. };

Without detached, the occurrences of User inside the set shape would be bound to the set of users named "Dave". However, in this context we want to run an unrelated query on the “unbound” User set.

  1. # does not work!
  2. update User
  3. filter .name = 'Dave'
  4. set {
  5. friends := (select User filter .name = 'Alice'),
  6. coworkers := (select User filter .name = 'Bob')
  7. };

Instead of explicitly detaching a set, you can create a reference to it in a with block. All declarations inside a with block are implicitly detached.

  1. with U1 := User,
  2. U2 := User
  3. update User
  4. filter .name = 'Dave'
  5. set {
  6. friends := (select U1 filter .name = 'Alice'),
  7. coworkers := (select U2 filter .name = 'Bob')
  8. };

operator

exists set

Set - 图7

exists set of anytype -> bool

Test whether a set is not empty.

exists is an aggregate operator that returns a singleton set {true} if the input set is not empty and returns {false} otherwise.

  1. select exists {1, 2};
  1. {true}

operator

anytype [is type]

Set - 图8

anytype [is type] -> anytype

Filter the set based on type.

The type intersection operator removes all elements from the input set that aren’t of the specified type. Additionally, since it guarantees the type of the result set, all the links and properties associated with the specified type can now be used on the resulting expression. This is especially useful in combination with backlinks.

Consider the following types:

  1. type User {
  2. required property name -> str;
  3. }
  4. abstract type Owned {
  5. required link owner -> User;
  6. }
  7. type Issue extending Owned {
  8. required property title -> str;
  9. }
  10. type Comment extending Owned {
  11. required property body -> str;
  12. }

The following expression will get all Objects owned by all users (if there are any):

  1. select User.<owner;

By default backlinks don’t infer any type information beyond the fact that it’s an Object. To ensure that this path specifically reaches Issue the type intersection operator must be used:

  1. select User.<owner[is Issue];
  2. # With the use of type intersection it's possible to refer to
  3. # specific property of Issue now:
  4. select User.<owner[is Issue].title;

function

assert_distinct()

Set - 图9

std::assert_distinct(s: set of anytype) -> set of anytype

Check that the input set contains only unique elements, i.e a proper set.

If the input set contains duplicate elements, assert_distinct raises a ConstraintViolationError. This function is useful as a runtime distinctness assertion in queries and computed expressions that should always return proper sets, but where static multiplicity inference is not capable enough or outright impossible.

  1. select assert_distinct(
  2. (select User filter .groups.name = "Administrators")
  3. union
  4. (select User filter .groups.name = "Guests")
  5. )
  1. {default::User {id: ...}}
  1. select assert_distinct(
  2. (select User filter .groups.name = "Users")
  3. union
  4. (select User filter .groups.name = "Guests")
  5. )
  1. ERROR: ConstraintViolationError: assert_distinct violation: expression
  2. returned a set with duplicate elements.

function

assert_single()

Set - 图10

std::assert_single(s: set of anytype) -> anytype

Check that the input set contains no more than one element.

If the input set contains more than one element, assert_single raises a CardinalityViolationError. This function is useful as a runtime cardinality assertion in queries and computed expressions that should always return sets with at most a single element, but where static cardinality inference is not capable enough or outright impossible.

  1. select assert_single((select User filter .name = "Unique"))
  1. {default::User {id: ...}}
  1. select assert_single((select User))
  1. ERROR: CardinalityViolationError: assert_single violation: more than
  2. one element returned by an expression

function

assert_exists()

Set - 图11

std::assert_exists(s: set of anytype) -> set of anytype

Check that the input set contains at least one element.

If the input set is empty, assert_exists raises a CardinalityViolationError. This function is useful as a runtime existence assertion in queries and computed expressions that should always return sets with at least a single element, but where static cardinality inference is not capable enough or outright impossible.

  1. select assert_exists((select User filter .name = "Administrator"))
  1. {default::User {id: ...}}
  1. select assert_exists((select User filter .name = "Nonexistent"))
  1. ERROR: CardinalityViolationError: assert_exists violation: expression
  2. returned an empty set.

function

count()

Set - 图12

std::count(s: set of anytype) -> int64

Return the number of elements in a set.

  1. select count({2, 3, 5});
  1. {3}
  1. select count(User); # number of User objects in db
  1. {4}

function

sum()

Set - 图13

std::sum(s: set of int32) -> int64std::sum(s: set of int64) -> int64std::sum(s: set of float32) -> float32std::sum(s: set of float64) -> float64std::sum(s: set of bigint) -> bigintstd::sum(s: set of decimal) -> decimal

Return the sum of the set of numbers.

The result type depends on the input set type. The general rule is that the type of the input set is preserved (as if a simple + was used) while trying to reduce the chance of an overflow (so all integers produce int64 sum).

  1. select sum({2, 3, 5});
  1. {10}
  1. select sum({0.2, 0.3, 0.5});
  1. {1.0}

function

all()

Set - 图14

std::all(values: set of bool) -> bool

Generalized boolean and applied to the set of values.

The result is true if all of the values are true or the set of values is {}. Return false otherwise.

  1. select all(<bool>{});
  1. {true}
  1. select all({1, 2, 3, 4} < 4);
  1. {false}

function

any()

Set - 图15

std::any(values: set of bool) -> bool

Generalized boolean or applied to the set of values.

The result is true if any of the values are true. Return false otherwise.

  1. select any(<bool>{});
  1. {false}
  1. select any({1, 2, 3, 4} < 4);
  1. {true}

function

enumerate()

Set - 图16

std::enumerate(values: set of anytype) -> set of tuple<int64, anytype>

Return a set of tuples of the form (index, element).

The enumerate() function takes any set and produces a set of tuples containing the zero-based index number and the value for each element.

The ordering of the returned set is not guaranteed, however the assigned indexes are guaranteed to be in order of the original set.

  1. select enumerate({2, 3, 5});
  1. {(1, 3), (0, 2), (2, 5)}
  1. select enumerate(User.name);
  1. {(0, 'Alice'), (1, 'Bob'), (2, 'Dave')}

function

min()

Set - 图17

std::min(values: set of anytype) -> optional anytype

Return the smallest value of the input set.

  1. select min({-1, 100});
  1. {-1}

function

max()

Set - 图18

std::max(values: set of anytype) -> optional anytype

Return the greatest value of the input set.

  1. select max({-1, 100});
  1. {100}