← Back to context

Comment by ldb

7 years ago

Assume I have a table "Actors" with a column "age" and for some of the records the age is not set (an empty set). Does this mean that "SELECT SUM(age) FROM Actors;" gives "{}" or do you implement a special logic for empty-set summation when used in connection with aggregation (like SQL does)?

Aggregate functions in EdgeDB have an "initial value", which, for `sum()` is defined as zero. Other aggregates, like `avg()` are not defined for empty sets (you cannot divide by 0), so an error is thrown in this case.

  • I am still a bit unclear about this. Assume we have three actor records where two records have age=30 and for the remaining one the age is not set. From what I understand then "SELECT sum(age) FROM Actor;" returns "60" while "SELECT 30 + 30 + {}" returns "{}". This appears to be an inconsistent handling of empty sets (thought it would be the same as in SQL).

    • The difference is that `+` is defined as a strict function (returns empty on empty input): plus(a, b), whereas sum() is an aggregate that is specifically defined as 0 on empty input.

The sum of an empty set is, in fact, 0 (the identity for addition).

The generalized conjuction (we have a function called "all" for that) of an empty set is True (the identity for conjunction).

The generalized disjuction (we have a function called "any" for that) of an empty set is False (the identity for disjunction).

All of the above "sum", "all", and "any" are basically aggregate functions that operate on sets as a whole.

There is no special logic that you wouldn't get from considering these operations generalized for a set.

  • Thanks, that was helpful. However, I still think that having "sum(1,1,{})" returning "2" and "1+1+{}" returning "{}" can be viewed as somewhat inconsistent.

    • Let me make a tiny correction to the expression you wrote:

      "sum({1, 1, {}})" - the function sum takes only one argument and it's a set. Because we flatten all "nested" sets, the expression "{1, 1, {}}" is equivalent to "{1} UNION {1} UNION {}".

      The expression "1 + 1 + {}" albeit valid grammatically, can be equivalently re-written as "{1} + {1} +{}". At this point it should be far more obvious why "sum({1} UNION {1} UNION {})" is not the same as "{1} + {1} + {}".

      Literals may be a little confusing because they look like elements, but they are still sets, singleton sets, specifically. There's practical value in simply thinking about "a bunch of things: A, B, C", where each of the A, B and C can themselves be empty, a single thing, or a bunch of things while ignoring nesting. In our case we allow duplication in these bunches (which is not part of the bunch theory: http://www.cs.toronto.edu/~hehner/bunch.pdf). However, because most people are familiar with sets we find it easier to keep using the terms "set" and "multi-set" (and stipulate that they are flattened) in explanations.

      In general, the way the operator "+" works is this: A + B = {a + b : for all a in A, for all b in B}. Whereas the expression "{A, B}" is defined to be equivalent to "A UNION B".

      7 replies →