Search...
ctrl/
Light
Dark
System
Sign in

Gel v6

To explore the new features, ensure you specify version 6.0 when initializing your project. Pre-release versions are not considered stable and will not be automatically suggested:

Copy
$ 
gel project init --server-version 6.0-rc.2

Local instances

To upgrade a local project, first ensure that your CLI is up to date with gel cli upgrade. Then run the following command inside the project directory.

Copy
$ 
gel project upgrade --to-testing

Alternatively, specify an instance name if you aren't using a project:

Copy
$ 
gel instance upgrade -I my_instance

The CLI will check if your schema can migrate cleanly to Gel 6.0. If any issues are found, they will be reported.

Hosted instances

To upgrade a remote instance, we recommend the following dump-and-restore process:

  1. Gel v6.0 supports PostgreSQL 14 or above. Verify your PostgreSQL version before upgrading Gel. If you're using Postgres 13 or below, upgrade Postgres first.

  2. Spin up an empty 6.0 instance. You can use one of our deployment guides.

    For Debian/Ubuntu, when adding the Gel package repository, use this command:

    Copy
    $ 
      
      
      
    echo deb [signed-by=/usr/local/share/keyrings/gel-keyring.gpg] \
      https://packages.geldata.com/apt \
      $(grep "VERSION_CODENAME=" /etc/os-release | cut -d= -f2) main \
      | sudo tee /etc/apt/sources.list.d/gel.list
    Copy
    $ 
    sudo apt-get update && sudo apt-get install gel-6

    For CentOS/RHEL, use this installation command:

    Copy
    $ 
    sudo yum install gel-6

    In any required systemctl commands, replace edgedb-server-5 with gel-server-6.

    For Docker setups, use the 6.0 tag.

  3. Take your application offline, then dump your v5.x database with the CLI:

    Copy
    $ 
    gel dump --dsn <old dsn> --all --format dir my_database.dump/

    This will dump the schema and contents of your current database to a directory on your local disk called my_database.dump. The directory name isn't important.

  4. Restore the empty v6.x instance from the dump:

    Copy
    $ 
    gel restore --all my_database.dump/ --dsn <new dsn>

    Once the restore is complete, update your application to connect to the new instance.

    This process will involve some downtime, specifically during steps 2 and 3.

You can now use SQL DML (insert, update, delete) when connecting to your Gel instance via the PostgreSQL protocol. Our aim is to support most typical use cases from tools like SQL ORMs and SQL clients.

This allows more developers to use Gel, leveraging our advanced data model, tooling, and high-performance connection management. Teams can migrate their existing SQL codebases to Gel without rewriting their queries. Once adopted, you can gradually take advantage of EdgeQL's powerful query capabilities.

Existing Gel users who already use EdgeQL can benefit too. While some SQL features like window functions, recursive queries, and explicit locking are not yet supported, you can use these features in SQL today. We will continue to add support for more features in the future.

We aim for this version to be the last requiring a full dump and restore process for major version upgrades. We understand that dump-and-restore is disruptive, so enabling in-place upgrades will make it easier for teams to upgrade more frequently.

We now store statistics about query performance. These statistics are available in sys::QueryStats objects.

Copy
select sys::QueryStats {
  query,
  queryType,
  tag,
  plans,
  total_plan_time,
  mean_plan_time,
  calls,
  total_exec_time,
  mean_exec_time,
} filter .branch.name = sys::get_current_branch();

More details to come in the reference documentation.

We've added support for the popular PostGIS extension for PostgreSQL. This extension adds support for geographic objects and spatial data types.

We've introduced a new standard library module for sending network requests, initially supporting HTTP. This module schedules asynchronous requests and allows you to poll for responses.

We've introduced several new features to our authentication extension:

  • You can now configure generic OpenID Connect providers.

  • If using an OAuth provider that returns an id_token (like an OpenID Connect compatible provider), you will now receive that validated token in your callback. This simplifies using some of that data for your own User or Profile objects, saving a roundtrip to the identity provider.

  • As an alternative (or in addition) to configuring SMTP for sending emails, you can now configure a webhook for various authentication lifecycle events. Use these webhooks to send custom emails, update analytics, or trigger other workflows.

  • Previously, a missing PKCE session during email verification was treated as an error. Now, we support verifying end-user emails from a different device than the one used to start the sign-up or sign-in process. To enable verification without PKCE, direct the end-user to attempt a login after verifying their email, which will initiate a new flow.

    Previously, the application couldn't identify which identity was being created during sign-up until email verification was successful. When verification occurred on the same device, it concluded with an auth token, allowing the creation of a new User based on that token's identity. With the new process, where users are directed to sign in after email verification, there's no clear distinction between a regular sign-in (which shouldn't create a new User) and an interrupted sign-up (which should create a new User). To address this, we now return an identity_id in the sign-up response, enabling you to create a User type before the email is verified.

  • We now configure a development-only SMTP provider for instances hosted on our Cloud. This SMTP proxy is heavily rate limited, and requires a fixed sender email address. It is intended to be used for development and testing purposes. Once you're ready to start sending real emails, you can configure your own SMTP provider. We hope this will make it easier to get started with a simple email-based authentication flow during early development.

  • Handle multiple WebAuthn email factors. (#7861)

  • Add logs to auth extension. (#7944)

  • Migrate ext::auth::SMTPConfig to cfg::EmailProvider. (#7942)

  • Allow Magic Link to specify a custom link URL. (#8030)

  • Do not fail if SMTP provider is not configured. (#8228)

Breaking changes

  • We have moved our SMTP configuration into a new top-level cfg::SMTPProviderConfig configuration object. During the upgrade process, your existing SMTP configuration will be migrated to this new object. If you have any scripts that configure SMTP directly, update them to use the new object.

  • We've updated the built-in list of models from our first-party LLM providers to match the latest offerings from OpenAI, Anthropic, and Mistral.

  • We now pass LLM configuration query parameters through to the downstream provider.

  • Add delays to AI embeddings requests based on rate limits provided by provider.

  • Allow specifying underlying vector dimensions when creating an index. (#8068)

We've simplified the scoping rules for queries. See our RFC 1027 outlining the changes.

The RFC highlights two main reasons for removing path factoring: the need to simplify and enhance the language, and concerns about implementation. Path factoring is complex and makes it hard to quickly understand a query's behavior. It also undermines several key design principles of EdgeQL. Although EdgeQL is intended to be read from top to bottom, path factoring allows later parts of a query to change its meaning significantly.

By default in 6.0, we will generate new schemas that opt-in to the new scoping rules. Existing schemas will continue to use the old rules and emit warnings when queries that trigger the old behavior are encountered at query time.

We've added hooks for gel CLI operations. Certain operations like switching branches or applying migrations have a profound effect on the state of the database. These types of changes may occasionally need to be synchronized with the rest of the project codebase. Whether it's a need to re-run some schema introspection tools or some fixture validation or re-generation tools, we now have a way to add hooks that will automatically execute after certain commands in your project.

These hooks are declared in the gel.toml (or deprecated edgedb.toml) file. For example:

[hooks]
schema.update.after="scripts/extract_schema_docs.sh"

This would run scripts/extract_schema_docs.sh script any time the schema changes (whether due to branch switch or applying a migration). In this example the script is meant to introspect the schema annotations and automatically generate some documentation files used in the project. But the mechanism is flexible enough to be used for automating a variety of project tasks.

See our RFC 1028 for more detials on the changes.

We've also added a way to respond to certain file changes within a project. The gel.toml (or deprecated edgedb.toml) now supports [[watch]] configuration to specify the files being watched and the script to be executed when changes occur. In order to enable this mode the gel watch command is used.

For example, the following configuration will watch for changes in the queries files and automatically attempt to re-generate the functions that allow executing these queries in a type-safe way:

[[watch]]
files = ["queries/*.edgeql"]
script = "npx @edgedb/generate queries"

Multiple [[watch]] entires can be added to the gel.toml (or deprecated edgedb.toml) file, so that you can fine-tune how your project responds to important file changes.

This changes how watch command funcitons. By default, gel watch will start the watch process and monitor files specified in gel.toml (or deprecated edgedb.toml). In order to access the old functionality of edgedb watch (which was monitoring schema file changes and automatically applying them to the database) you now need to run gel watch --migrate.

See our RFC 1028 for more detials on the changes.

  • Free objects no longer have an id property. This is a breaking change, though we expect the real-world impact to be minor. If you need a dynamically generated new ID for free objects, it can be added manually, using one of our UUID generation functions.

    Copy
    select {
        id := uuid_generate_v1mc(),
        property := 'Some string',
    }
  • Add __default__ keyword to refer to default value. (#7214)

    This keyword allows referring to the default value in insert and update statements. For example, consider the following schema:

    Copy
    type Item {
        name: str { default := 'New item' }
    }

    We can then insert a 'New item #1' by using the __default__ value:

    Copy
    db> 
    insert Item {name := __default__ ++ ' #1'};
    {default::Item {id: ebcfff62-eb91-11ef-a6b9-5ffb2f0b2940}}
    Copy
    db> 
    select Item{name};
    {default::Item {name: 'New item #1'}}
  • Add support for type expressions in intersections. (#7172)

    Allow using & and | in expressions like this:

    Copy
    select Shape[is Circle | Triangle & HasRightAngle];
  • Add array modifying functions array_set() (added in 6.0) and array_insert() (added in 6.0). (#7427)

  • Add trigonometry functions. (#8071)

    Add math::pi(), math::acos(), math::asin(), math::atan(), math::atan2(), math::cos(), math::cot(), math::sin(), math::tan().

  • Allow update and delete on type intersections. (#7655)

    Given types A, B, and C, allows expressions such as:

    Copy
    update A[is B & C]
    set { foo := 123 }
  • Implement \(expr)-style string interpolation. (#8210)

    This enables the following expression:

    Copy
    db> 
    select "1 + 1 = \(1 + 1)"
    {'1 + 1 = 2'}
  • Allow complex types as function params. (#7759)

    Allow functions such as:

    Copy
    function foo(x: A | B) -> int64 using (x.n);
  • Search std for module name when using with clause. (#7753, #7836, #7743)

    We've consolidated many of the built-in modules as sub-modules under the std umbrella.

  • Support accessing link properties through for bindings. (#7805)

    Now you can write something like this:

    Copy
    select User {
        cards := ((
            for c in .deck[is HeartsCard]
            select (c.name, c@order)
        )),
    }
  • Enable DML in user-defined functions. (#7945)

    It is now possible to create this kind of function:

    Copy
    function add_foo(x: int64) -> Foo using ((
        insert Foo { val := x }
    ));

    A new Modifying volatility level is introduced to represent this. (#7808)

  • Support drop extension package of user-installed extensions. (#7926)

  • Warn when a filter clause has Many cardinality. (#8089)

  • Mark assert_exists(), assert_single(), and assert_distinct() functions as being Immutable. (#8292)

  • Expose administer statistics_update(). (#8335)

  • Require extension modules to live in ext::. (#7526)

  • Use LRU/MRU to improve connection re-use. (#7583)

  • Change how globals affect internal alias names that may appear in introspection. (#7641)

  • Rename sys::Database to sys::Branch. (#7653)

  • Add std::net and std::net::http modules. (#7676, #7736)

  • Add sys::Branch.last_migration. (#7654)

  • Record SDL in schema::Migration object. (#7673)

  • Get std::net::http max connections from config. (#7767)

  • Add extension ext::pg_unaccent. (#7741)

  • Implement warnings in the server. (#7823)

  • Update the ext::pgvector extension. (#7812)

    Add sparcevec and halfvec types and update indexes and operators.

  • Avoid computing globals json if not needed for inlined function. (#7920)

  • Allow volatile with in DML statements. (#7969)

  • Make admin the default role instead of edgedb. (#8010)

  • Support extension upgrades. (#7998)

  • Replace headers with annotations in Parse/Execute. (#8037)

  • Add TOML config file support. (#8121)

  • Allow tuples in GIN, GIST and BRIN indexes. (#8232)

  • Add a cors-always-allowed-origins option. (#8233)

  • Tweak parser to correctly report certain missing semicolons. (#7252)

  • Fix regression in using some tuple literals as a default. (#7281)

  • Fix handling of enums in arrays and multi properties in GraphQL. (#3990)

  • Improve error message when casting to collections. (#7300)

  • Improve json cast error messages. (#7312)

  • Improve error when accessing a non-existent tuple field. (#7373)

  • Fix an ISE on some specific operations with arrays. (#7363)

  • Catch illegal aggregate calls in constraints and indexes during migration create. (#7343)

  • Raise error when computed global is set or reset. (#7374)

  • Improve error messages for casts, is, and introspect. (#7351)

  • Fix recursive definition error when computed property refers to different object's computed property. (#7431)

  • Fix issue with abstract types, exclusive constraints, and analyze. (#7454)

  • Fix an issue with deletion policies affecting properties. (#7675)

  • Fix errors when resolving type intersections. (#7662)

  • Fix issues with branch commands that arise from network issues. (#7773)

  • Fix a regression involving optional arguments and assert_exists(). (#7798)

  • Include more information in HTTP protocol errors. (#7817)

  • Raise error when passing multi cardinality args to modifying functions. (#7816)

  • Fix an issue with cardinality of json parameters. (#7843)

  • Encode offset positions as integers in json error encoding. (#7842)

  • Make configure current database block until configuration is actually set. (#7865)

  • Fix shape not being copied when inlining parameters. (#7872)

  • Garbage collect std::net::http::ScheduleRequest. (#7888)

  • Fix error when dropping non overloaded function. (#7899)

  • Fix embedding data being stored with the wrong entry. (#7932)

  • Fix an obscure bug deleting doubly nested alias tuples. (#7956)

  • Fix an schema issue with deleting collections. (#7957)

  • Automatically create array types for all scalars to avoid introspeciton issues. (#7970)

  • Fix an edge case of calling value functions from range vars. (#7982)

  • Fix ISE when enumerating a call to an aggregate function. (#7988)

  • Fix free objects being materialized as if they are volatile. (#8000)

  • Fix aliases always being considered Immutable. (#8009)

  • Fix ISE when taking intersection of types with pointers of the same name. (#8012)

  • Fix static types in subtypes under sysconfig. (#8054)

  • Fix extension package installation on non --testmode servers. (#8096)

  • Fix cache key of source. (#8103)

  • Fix handling of invalid link properties. (#8156)

  • Delete old .s.EDGEDB.admin.XXX sockets. (#8248)

  • Fix broken error messages for type mismatches in a number of schema objects. (#8294)

  • Don't emit instance configs matching their defaults in describe instance config. (#8316)