1.0 Alpha 2

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

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:

$ npm install edgedb

and it is ready for use:

const edgedb = require("edgedb");

async function main() {
  const conn = await edgedb.connect({
    user: "edgedb",
    host: "127.0.0.1",
  });

  try {
    console.log(await conn.fetchOne("SELECT 1 + 1"));
  } finally {
    await conn.close();
  }
}

main();

The documentation can be found here.

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:

db> 
SELECT 1n IS std::bigint;
{true}
db> 
SELECT 1.0n IS std::decimal;
{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.

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.)

  • 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).

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.

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:

SELECT User {
    favorites: {
        title
    }
}
FILTER .id = <uuid>$id;

Using the [IS ...] operator we can filter the set of user favorites:

SELECT User {
    # the old syntax was "favorites: Book {...}"
    favorites[IS Book]: {
        title
    }
}
FILTER .id = <uuid>$id;

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

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

SELECT User.<profile[IS Profile].settings;

(See #969 for details.)

  • 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).

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

query {
  UserGroup(
    filter: {settings: {name: {eq: "setting06"}}}
  ) {
    name
    settings {
      name
      value
    }
  }
}

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:

mutation update_Foo(
  filter: ...,
  order: ...,
  first: ...,
  last: ...,
  before: ...,
  after: ...,

  data: {
    prop1: {clear: true},
    prop2: {set: "new value"},
    link1: {set:
      [{
        # objects can be specified via
        # the same interface as a query
        filter: ...,
        order: ...,
        first: ...,
        last: ...,
        before: ...,
        after: ...
      }]
    }
  }
) {
  id
  prop1
  ...
}
  • Fix backward links in aliases (#990).

  • Fix covarinat types support (#709).

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

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).

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

db> 
DESCRIBE TYPE Movie AS DDL;
{
  'CREATE TYPE default::Movie EXTENDING default::HasImage {
    CREATE SINGLE PROPERTY avg_rating := (WITH
      MODULE default
    SELECT
      math::mean(.<movie[IS Review].rating)
    );

    ...
  };'
}
db> 
DESCRIBE TYPE Movie AS TEXT VERBOSE;
{
  'type default::Movie extending default::HasImage {
    index on (__subject__.image);

    required single link __type__ -> schema::Type {
      readonly := true;
    };

    required single property id -> std::uuid {
      readonly := true;
      constraint std::exclusive;
    };

    required single property image -> std::str;

    ...
  };'
}

(Issue #790.)

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

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

The REPL now recognizes a number of introspection commands:

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

For example:

db> 
\lt
------------------- Object Types -------------------
 Name              | Extending
-------------------+--------------------------------
 default::HasImage | std::Object
 default::Movie    | default::HasImage, std::Object
 default::Person   | default::HasImage, std::Object
 default::Review   | std::Object
 default::User     | default::HasImage, std::Object

db> 
\d HasImage
abstract type default::HasImage {
  required single link __type__ -> schema::Type {
    readonly := true;
  };
  required single property id -> std::uuid {
    readonly := true;
  };
  required single property image -> std::str;
};

(Issue #179.)

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.)

EdgeDB is now based on PostgreSQL 12.

  • 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.

  • 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.