1.0 Alpha 2​

This changelog summarizes new features and breaking changes in EdgeDB 1.0 alpha 2.

New JavaScript Driver​

EdgeDB has a new high-performance native EdgeDB driver for NodeJS 10+.

The driver is written in strict TypeScript, thoroughly tested, and has first-class async/await support. It is at least twice as efficient as comparable current PostgreSQL JavaScript drivers.

Install it with npm or yarn:

  1. npm install edgedb

and it is ready for use:

  1. const edgedb = require("edgedb");
  2. async function main() {
  3. const conn = await edgedb.connect({
  4. user: "edgedb",
  5. host: "127.0.0.1",
  6. });
  7. try {
  8. console.log(await conn.fetchOne("select 1 + 1"));
  9. } finally {
  10. await conn.close();
  11. }
  12. }
  13. main();

The documentation can be found here.

Standard Library​

std::bigint​

The new std::bigint scalar type is an arbitrary precision integral type. The motivation for the new type is that many platforms lack a true multi-precision decimal type, but implement an arbitrary-precision integer type (JavaScript is a prominent example). The n suffix on numeric literals can now be used to express both std::bigint and std::decimal:

  1. select 1n is std::bigint;
  1. {true}
  1. select 1.0n is std::decimal;
  1. {true}

The std::bigint and std::decimal maintain the relationship that is similar to the relationship between std::int64 and std::float64. All sized integer types are implicitly castable to bigint, and bigint itself can implicitly cast to std::decimal.

New “cal” Module​

Non-timezone aware date/time types and functions are moved into the new cal module. This separation promotes std::datetime to be the default safe choice for most use cases. The types in the cal:: module are useful to implement calendars, alarms, reminders, and other cases where time is relative and imprecise. The updated date/time types are listed below:

std::datetime

A timezone-aware date/time type.

std::duration

An absolute time interval. Can be unambiguously used with both std::datetime and cal::local_datetime types.

cal::local_datetime

Represents date and time without time zone.

cal::local_date

Represents date without time zone and time components.

cal::local_time

Represents time without time zone and date components.

Type conversion between timezone-aware std::datetime and local date/time values (types in the cal:: module) is always explicit and unambiguous.

(See #902 for details.)

Other Fixes and Enhancements​

  • Prohibit NaN as a std::decimal value (5e16ace1).

  • Rename std::datetime_trunc to std::datetime_truncate (#952).

  • Make datetime_get() and datetime_truncate() stricter (#958).

  • Disable days and months units in duration (#947).

  • Rename sys::transaction_isolation_t to sys::TransactionIsolation (c45ee4ba).

  • Rename schema::cardinality_t to schema::Cardinality (b2ceaa61).

  • Rename schema::target_delete_action_t to schema::TargetDeleteAction (6a7c6787).

  • Rename schema::operator_kind_t to schema::OperatorKind (3a01f616).

  • Rename schema::volatility_t to schema::Volatility (16e263cc).

Dump / Restore​

The new edgedb dump and edgedb restore commands can be used to safely dump and restore EdgeDB databases, including when upgrading to new versions of EdgeDB.

EdgeQL​

[is …] Operator​

The [is …] operator is now used to specify the link target type in shapes. Consider the following query that fetches a User along with everything linked to it via the favorites link:

  1. select User {
  2. favorites: {
  3. title
  4. }
  5. }
  6. filter .id = <uuid>$id;

Using the [is …] operator we can filter the set of user favorites:

  1. select User {
  2. # the old syntax was "favorites: Book {...}"
  3. favorites[is Book]: {
  4. title
  5. }
  6. }
  7. filter .id = <uuid>$id;

This change makes the shape construct consistent with the paths syntax and removes potential confusion with the similarly looking computed expressions in shapes.

Another change is related to backlink navigation. Starting with Alpha 2 it is required to use the [is …] operator in order to access target objects’ properties and links:

  1. select User.<profile[is Profile].settings;

(See #969 for details.)

Other Fixes and Enhancements​

  • Update the semantics of line continuation (trailing \) in strings (#921).

  • Remove the .> alternate syntax for forward link navigation (#982).

  • Fix interaction of the for statement and nested shapes (#834).

  • Place restrictions on the use of DML statements (#741).

  • Fix queries with unions with overlapping subtypes (#1010).

  • Allow trailing commas in the with clause (#868).

  • Ban use of :: in quoted names (#840).

  • Add syntax for quoting backticks in quoted names (#632).

  • Remove select-like clauses from the for statement (#743).

  • Fix implicit id and __tid__ properties injection in DML statements (#664).

  • Make type variants made by shapes consistent with schema inheritance rules (36e86d56).

  • Implement rudimentary support for type intersection (177aa1f8).

  • Optimize single link type indirections when possible (48cdfa54).

  • Stop enforcing common prefix ambiguity restriction on tuple dereference (9011c821).

  • Add an error hint for incorrect string line continuation (7b982e09).

  • Enable comparison of collections of distinct (but compatible) types (c913df11).

  • Implement std::IN as a derivative of std::= (f3682e92).

GraphQL​

Enhanced Filtering​

It is now possible to filter by traversing arbitrarily deep links, not just immediate properties:

  1. query {
  2. UserGroup(
  3. filter: {settings: {name: {eq: "setting06"}}}
  4. ) {
  5. name
  6. settings {
  7. name
  8. value
  9. }
  10. }
  11. }

Mutations​

Insert, update, and delete mutations are now supported.

Mutations support all the same parameters as a query like filter, order, first, last, after, and before.

Insert and update mutations accept a data parameter that allows to specify what data to insert or how to update the existing data:

  1. mutation update_Foo(
  2. filter: ...,
  3. order: ...,
  4. first: ...,
  5. last: ...,
  6. before: ...,
  7. after: ...,
  8. data: {
  9. prop1: {clear: true},
  10. prop2: {set: "new value"},
  11. link1: {set:
  12. [{
  13. # objects can be specified via
  14. # the same interface as a query
  15. filter: ...,
  16. order: ...,
  17. first: ...,
  18. last: ...,
  19. before: ...,
  20. after: ...
  21. }]
  22. }
  23. }
  24. ) {
  25. id
  26. prop1
  27. ...
  28. }

Other Fixes and Enhancements​

  • Fix backlinks in aliases (#990).

  • Fix covariant types support (#709).

  • Implement explicit handling of 64-bit integers, and arbitrary precision integers and decimals (#1138).

DDL / SDL / Schema​

DDL and SDL layers are heavily refactored in alpha 2. A lot of issues were fixed; this section lists only new features and backwards incompatible changes:

  • Rename “views” to “expression aliases” (#989).

  • Add a “module” block to SDL (#907).

  • Rename SDL keyword “inherited” to “overloaded”. (#806).

  • Reimplement SDL through DDL. (824f14a6).

  • Rename the DDL from clause to using (4194ab46).

  • Add support for collection type views 367820ba.

  • Prohibit multi or required link properties (#994).

  • Forbid redefinition of read-only flag. (#1048).

  • Change set annotation to create/alter annotation (0e53e2ff).

  • Implement create module if not exists (27924c10.)

  • Allow indexes to be annotated (50d8809a).

  • Remove explicit index names (e0f462c2).

  • Enforce correct expression cardinality and type in link/property default (2f6039fc and 9fa18afb).

Introspection​

Generic Describe​

The new describe introspection command can generate DDL, SDL, or a descriptive text summary of any schema object in EdgeDB. A few examples:

  1. describe type Movie as ddl;
  1. {
  2. 'CREATE TYPE default::Movie EXTENDING default::HasImage {
  3. CREATE SINGLE PROPERTY avg_rating := (WITH
  4. MODULE default
  5. SELECT
  6. math::mean(.<movie[is Review].rating)
  7. );
  8. ...
  9. };'
  10. }
  1. describe type Movie as text verbose;
  1. {
  2. 'type default::Movie extending default::HasImage {
  3. index on (__subject__.image);
  4. required single link __type__ -> schema::Type {
  5. readonly := true;
  6. };
  7. required single property id -> std::uuid {
  8. readonly := true;
  9. constraint std::exclusive;
  10. };
  11. required single property image -> std::str;
  12. ...
  13. };'
  14. }

(Issue #790.)

Other Enhancements​

  • schema::bases and schema::ancestors are now ordered via the @order link property (#854).

  • Add schema::Module.builtin attribute (64f88a01).

REPL​

Introspection​

The REPL now recognizes a number of introspection commands:

  1. (options: S = show system objects, I = case-sensitive match)
  2. \d[+] NAME describe schema object
  3. \l list databases
  4. \lr[I] [PATTERN] list roles
  5. \lm[I] [PATTERN] list modules
  6. \lT[IS] [PATTERN] list scalar types
  7. \lt[IS] [PATTERN] list object types
  8. \la[IS+] [PATTERN] list expression aliases
  9. \lc[I] [PATTERN] list casts

For example:

  1. \lt
  1. ------------------- Object Types -------------------
  2. Name | Extending
  3. -------------------+--------------------------------
  4. default::HasImage | std::Object
  5. default::Movie | default::HasImage, std::Object
  6. default::Person | default::HasImage, std::Object
  7. default::Review | std::Object
  8. default::User | default::HasImage, std::Object
  1. \d HasImage
  1. abstract type default::HasImage {
  2. required single link __type__ -> schema::Type {
  3. readonly := true;
  4. };
  5. required single property id -> std::uuid {
  6. readonly := true;
  7. };
  8. required single property image -> std::str;
  9. };

(Issue #179.)

Auto Limit​

The REPL now automatically injects limits to user queries so that a simple select Log does not fetch all data from the database. Auto limits are only enabled in parts of the query that return visible data; auto limits are disabled inside aggregate functions, so analytical queries work as expected.

The auto-limit can be disabled with a \limit 0 command, or the limit can be changed with \limit 42 command.

(Issue #846.)

Server​

Postgres 12​

EdgeDB is now based on PostgreSQL 12.

Other Fixes and Enhancements​

  • Add an explicit database instance compatibility check (251517c0).

  • Initial support for using a remote Postgres cluster as a backend (b0db89b2).

  • Protocol: prohibit tuples as query arguments (#745).

  • Protocol: differentiate SASL message types (d52885c8).

  • Protocol: Add “Terminate” message for graceful shutdown (d699352a).

  • Protocol: use 32-bit length-prefixed strings everywhere.

  • Drop reliance on a custom PostgreSQL C extension.

Misc​

  • Command-line tools now use -h for help; -H for hostname. (#1039).

  • edgedb subcommands were renamed to have dashes in their names instead of spaces, e.g. edgedb create role became edgedb create-role (#1039).

  • Rename the --pidfile argument of edgedb-server to --pidfile-dir. (#1093).

  • Add command line arguments to edgedb-server for automatic temporary cluster bootstrap to simplify CI (5161de72).

  • Add developer tools for memory and performance profiling (#1032, #835, and #858).

  • Improve query compilation performance by ~30%.

  • Strictly type-annotate SQL and IR compilers, run mypy in strict mode in CI for critical modules.

  • Upgrade to Python 3.8.