1.0 RC 2
This changelog summarizes new features and breaking changes in EdgeDB 1.0 Release Candidate 2 “Lacaille”.
Migrations
We continue fixing bugs that affect schema definitions and migrations. The most notable changes involve static cardinality inference, so that computed links and properties can be defined to mimic their regular counterparts:
Fix creation of required computed links (#2985).
This allows having
required
links in the schema even if they are computed:
```
type User {
required link profile -> Profile;
}
type Profile {
required link user := assert_exists(.<profile[is User]);
}
```
Fix issues when migrating between regular and computed links and properties (#2411).
Fix issues when changing cardinality of computed links and properties (#3003).
Fix how
alter
suggestions are rejected when processing migrations, making sure that they don’t repeat (#3111).
EdgeQL
Make static analysis correctly handle the cardinality of things wrapped in enumerate() (#3014).
This means that if you wrap a single property into enumerate() it still is correctly inferred to produce no more than one result:
```
select User {comp := enumerate(.name)};
```
```
{default::User {comp: (0, 'alice')}}
```
Fix some issues with enumerate() applied to the results of another function (#3025).
Fix assert_distinct() on tuples (#2990).
Fix a case where for over an empty set erroneously produced a non-empty result (#3012).
Fix exclusive constraint issue when conflicting entries are inserted at the same time (#3022).
Fix issues with how tuple elements are correlated (#3001).
Fix how functions or operators with
optional
parameters such as ?? interact with shape subqueries (#3008).This makes it possible to have a shape as one element of a tuple to be correlated with the expression in the other tuple element:
```
select (
User {name, friends: {name}},
User.friends.name ?? 'n/a'
);
```
```
{
(
default::User {
name: 'Alice',
friends: {default::User {name: 'Billie'}},
},
'Billie',
),
(
default::User {
name: 'Alice',
friends: {default::User {name: 'Cameron'}},
},
'Cameron',
),
(
default::User {
name: 'Alice',
friends: {default::Bot {name: 'Dana'}},
},
'Dana',
),
(default::User {name: 'Billie', friends: {}}, 'n/a'),
(default::User {name: 'Cameron', friends: {}}, 'n/a'),
(
default::Bot {
name: 'Dana',
friends: {default::User {name: 'Billie'}},
},
'Billie',
),
}
```
Fix issues with arrays of objects of related types (#2256).
Trying to build an array where elements are not of the same object type, but of related types no longer produces an error:
```
select [(select User filter .name = 'alice'), (select SystemUser)];
```
```
{
[
default::User {id: 8f69777e-3129-11ec-ba91-0f55d65fd8d7},
default::SystemUser {id: 89c0e596-3129-11ec-ba91-2f631728aea3},
],
}
```
Conceptually, there’s no difference between first creating a set via [union]($f4a08709faa70d7b.md#operator::union) and using [array\_agg()]($42a702d413ab2a05.md#function::std::array_agg) on it or using an array constructor directly and supply the individual elements as subqueries.
Fix many bugs with objects inside arrays and tuples (#2992).
Packing and unpacking objects into arrays and tuples now works more reliably. You can make use of the different way of selecting the data, aggregate it using array_agg() or by some other means and still be able to access the elements to get their nested contents in queries:
```
select [(User,)][0];
```
```
{
(default::User {id: 8f69777e-3129-11ec-ba91-0f55d65fd8d7}),
}
```
```
select ([User],).0;
```
```
{
[default::User {id: 8f69777e-3129-11ec-ba91-0f55d65fd8d7}],
}
```
Fix some issues with ad-hoc computed links or properties inside arrays (#2979).
Fix and to consistently apply to properties and produce an
{}
even for the case ofFalse and {}
(#3121).Reserve
never
as a keyword for future use (#3102).
GraphQL
Make
and
andor
in GraphQL use “short-circuiting” logic.In EdgeQL and and or produce
{}
if any of the operands are{}
. There are different ways of handling the{}
by using ?? or if..else operator. However, within the restricted context of operations reflected to GraphQLfilter
it makes sense to use “short-circuiting” versions of the operators and enforce that if any of the operands toor
aretrue
, so is the result and similarly if any of the operands toand
arefalse
so is the result.Hide
id
as well as computed links and properties from mutation (#3109).
Configuration
A lot of the configuration settings used to be strings that simply mapped to Postgres settings. We now use more appropriate types for expressing configuration values: bool, int64, duration, in addition to str.
We also introduce a new scalar cfg::memory to represent size of various memory storage in a clear and unambiguous way.
Bindings
We now have the client abstraction superceding the connection and pool abstractions. There’s no conceptual difference between a pool of size 1 and a single connection, so we decided that the API should reflect that. So we introduce a single concept of client to send queries to the database and let this client encapsulate the handling of concurrent connections.
We’re making our binding more robust by adding “retry options” to our interface. What it means is that read-only queries and all transactions can be automatically retried in case of certain kinds of errors (such as network errors) without the need for any extra code on the part of the developers. This also means that we no longer have “raw” and “retrying” transactions in the APIs, but all transactions are retrying. To get the same behavior as for “raw” transactions the maximum number of attempts can be explicitly specified as 1
.
We’re also in the process of cleaning up our APIs and removing the deprecated functions.
Support connection pooling by default and retry features for edgedb-python and release v0.18.0a2 driver.
Support connection pooling by default and retry features for edgedb-js and release v0.15.3 driver.
Support connection pooling by default and retry features for edgedb-go and release v0.8.3 driver.
Environment variable renames
For clarity and simplicity, several environment variables have been renamed and the set of supported values has been modified. The old variables have been deprecated and will be removed in a future release.
Old name | New name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Client configuration
EDGEDB_CLIENT_TLS_SECURITY
insecure
no_host_verification
strict
default
:no_host_verification
if custom certificate is supplied, otherwisestrict
New: EDGEDB_CLIENT_SECURITY
default
insecure_dev_mode
: for now, equivalent to settingEDGEDB_CLIENT_TLS_SECURITY=insecure
though this mode may encapsulate other behavior later
EDGEDB_RUN_VERSION_CHECK
cached == default
— run occasionallynever
— skips the check
EDGEDB_INSTALL_IN_DOCKER
(CLI only)
forbid == default
allow
— skips the check
Server configuration
EDGEDB_SERVER_BINARY_ENDPOINT_SECURITY
tls == default
optional
— allow no TLS
EDGEDB_SERVER_HTTP_ENDPOINT_SECURITY
tls == default
optional
— allow no TLS
EDGEDB_SERVER_SECURITY
strict == default
insecure_dev_mode
— disable password-based authentication and allow unencrypted HTTP traffic
EDGEDB_DOCKER_APPLY_MIGRATIONS
(Docker only)
always == default
never
EDGEDB_SERVER_TLS_CERT_MODE
require_file
— requires a valid TLS certificate and key to be specifiedgenerate_self_signed
generate self-signed certificate and private key on bootstrap if certificate or key are not specified or missingdefault
(equals torequire_file
ifEDGEDB_SERVER_SECURITY
is set tostrict
, equals togenerate_self_signed
ifEDGEDB_SERVER_SECURITY
is set toinsecure_dev_mode
)
EDGEDB_DOCKER_SHOW_GENERATED_CERT
always == default
never