1.0 RC 1

This changelog summarizes new features and breaking changes in EdgeDB 1.0 Release Candidate 1 “Epsilon Eridani”.

We continue fixing bugs that affect schema definitions and migrations:

  • Always escape newlines when string literals appear in automatically generated code, such as in migrations (#2704).

  • Fix behavior of set multi to make sure that it does not imply set required (#2778).

  • Make properties non-distinct by default (#2853).

    All values in EdgeQL are considered to be multisets, which are a generalization of the set concept that allows duplicate elements. For brevity we refer to multisets as just “sets”, and use “proper set” or “distinct set” when referring to proper mathematical sets.

    In EdgeDB the data is modeled as a directed graph, where objects are vertices and links are edges. Query path expressions ( are graph traversal operators and, by definition, always return a distinct set. This means that there can be no link of the same name between a pair of objects, and this also means that a set of objects pointed to by a multi link is always distinct. Computed links must follow this rule too so as to behave exactly like materialized links externally. To illustrate, consider a common case of finding a set of “friends of friends” of a particular user. In EdgeQL this is simply select User.friends.friends.

    Properties are different, because their value is scalar, and scalars lack true identity, which makes any proper set mechanics on scalar sets expensive due to explicit elimination of duplicates. Furthermore, non-distinct scalar sets are actually desirable in many queries, especially where analytics and tuples are involved. Finally, we should enforce consistent multiplicity rules on computed properties, and static inference of multiplicity on scalars is weak and will effectively force users to pollute queries with pointless and expensive distinct.

    Here we change EdgeDB behavior to allow multiplicity greater than one in multi properties.

  • Fix the error when an object function is created alongside its object (#2834).

  • Fix handling of function overloads on object type parameters (#2889).

    The current approach places a number of restrictions on overloads of object type functions:

    • there must be no difference in any but one parameter type, i.e. this is single dispatch

    • the names of all parameters must match

    These restrictions apply only to functions that are actually overloaded with a different object type. Overloading with scalar types is perfectly OK even if the rest of the parameter types differ:

    function func(a: Foo, b: int32) -> int64 using ( BODY );
    function func(a: Bar, b: int32) -> int64 using ( BODY );
    function func(a: str, b: int32, c: int64) -> int64 using ( BODY );
  • Make computed links and properties defined in the schema behave the same way as the equivalent computed links and properties defined ad-hoc directly in the query (#2558).

  • Drop final from the syntax (#2607).

  • Restore the precedence of detached to no longer match that of exists undoing the change #2638.

  • Fix unless conflict with inheritance hierarchies (#2525).

  • Always use serializable isolation (#2877).

  • Correctly raise exclusive constraints when performing an insert or an update on related types (#2845).

  • Enforce link or property cardinality in mutations (#2827).

  • Fix cardinality inference in “optionality-preserving” functions (#2844).

    A certain number of standard aggregate functions are guaranteed to preserve the lower cardinality bound of their argument. These functions are assert_single(), enumerate(), min(), and max().

    Unfortunately, there is currently no way to signal that lower cardinality is preserved for user-defined functions. We introduce the new std-only preserves_cardinality field, which is also exposed in the public introspection schema for the benefit of query builders and such.

  • Implement assert_exists() which allows to perform a cardinality check in run-time (#2901):

    select assert_exists((select User filter .name = "Administrator"));
    {default::User {id: ...}}
    select assert_exists((select User filter .name = "Nonexistent"));
    ERROR: CardinalityViolationError: assert_exists violation: expression
           returned an empty set.
  • Fix deletion issues for multi properties (#2883).

  • Disallow some broken DML/volatile interactions (#2811).

  • Fix volatility inference of functions taking object arguments to be at most Stable because it triggers a table scan (#2890).

  • Fix a regression when objects from opaque sources are passed to functions (#2924).

  • Fix accessing link properties on union types (#2513).

  • Fix some introspection issues with backlinks (#2599)

  • Fix bare backlink schema-defined computed link (#2605).

  • Make filtered backlinks work even when there exists a computed backlink (#2698).

  • Fix handling of the optional specifier in shapes to be similar to SDL (#2900).

  • Add the cli.toml global configuration file for customizing the CLI and REPL behavior. The location of the file is shown as “Config” by edgedb info.

  • Make SCRAM the default auth method (#2848).

  • Add a server option to specify the default authentication method (#2936).

    This patch adds the new --default-auth-method argument as well as its companion EDGEDB_SERVER_DEFAULT_AUTH_METHOD environment variable to set the default authentication method.

We’ve updated the binary protocol to version 0.12 which brings some performance and other improvements.

  • Support protocol 0.12 features for edgedb-python and release v0.18.0 driver.

  • Support protocol 0.12 features for edgedb-js and release v0.15.2 driver.

  • Support protocol 0.12 features for edgedb-go and release v0.8.2 driver.