Repository navigation
v2026.09.28
·
14 commits
to primary
since this release
Security
- SQL injection closed: date/duration unit arguments were pasted straight into SQL, and the REST router, GraphQL arguments, simple-protocol variables, cast targets and configure keys were not escaped properly.
- Configure locked down: configure system and configure database now require an admin, and only allowlisted keys are accepted. Before, anyone who could reach
/querycould runALTER SYSTEM. - Access policies enforced:
- Select policies now apply to every read, including with bindings, for loops, paths, sub-shapes and aggregates. Several of these bypassed them before.
- Update and delete must also pass the select policy.
- Written objects are checked against write policies after the write.
- Subtypes inherit their parents’ policies.
- Globals used in policies now work.
- Rate limiting: the auth, server and extension rate limiters are keyed by client IP. Before, one busy client could lock everyone out of login.
Server and bundled PostgreSQL
- Restart loop fixed: disc serve restarted Postgres every 30s because the health check called pg_isready, which the bundled build doesn't include. Disc Auth now reconnects instead of returning 500 "Broken pipe".
- Tools the bundled build lacks: monitor queries now run in-process. db dump, db restore and pg upgrade download checksum-verified client tools on first use.
- Upgrades and downloads: disc pg upgrade now works end to end and rolls back on failure. PostgreSQL downloads are verified against pinned SHA-256 hashes.
Migrations
- Changes that were silently skipped now apply:
- On-delete policy changes
- Link constraint exclusive
- Rewrite rules
- Expression and scalar-type constraints (now real CHECK constraints)
- Property defaults and index expressions
- Column types: bigint, user scalars and array columns get real types instead of TEXT. Existing TEXT columns are converted on the next migrate, and the migrate fails loudly on values that won’t convert.
- Rollback:
- disc migrate --rollback works now; it used to always fail with "No rollback SQL available".
- Dropped objects are recreated.
- Only what the migration created is undone.
- Migrations are ordered by the order they were applied rather than by timestamp.
- Drift repair now covers delete rules, triggers and column types.
EdgeQL: matching Gel’s semantics
- Filters no longer hit every row:
update Item filter Item.name = 'a'and the matching delete changed or deleted every row. The statement’s subject is now bound in its filter. - Operators:
- Division:
/returnsfloat64,//floors,%takes the divisor’s sign. ^is power.and/or/nothandle empty values the way Gel does.
- Division:
- Sets: set literals return one row per element, and operators, functions and multi-path comparisons apply per element.
- Newly supported:
- SDL functions (inlined at compile time)
- Grouping sets and group over selects
- Array and string slicing
- Nested arrays
- deferred restrict and if orphan
- Abstract types (reads union the subtypes; update and delete work)
- Nested mutations
- Other fixes:
- Upsert else filters and ordering with empty first/empty last
- Self-links
- Tuple comparison
<json>casts- ISO 8601 durations
- Value errors now use Gel’s messages and hints
Binary protocol and clients
- Binary protocol:
- Gel error codes are used. Constraint violations used to be sent with a code that clients retry.
- Real type descriptors for sets, with queries, arrays, tuples, nested shapes and groups; clients used to decode
{id: null}. bigintanddecimalvalues used to be sent as zero bytes.querySinglecardinality checks.
- Codegen and SDK:
- Cross-module enums and same-named scalars resolve correctly.
int64values come back asbigint, anddatetimes(including nested ones) asDate.bigintanddecimalkeep full precision.NaNand±Infinitywork in the Go and Rust clients.- The generated client now type-checks.
- CLI:
- migrate, codegen, schema, admin and ui exited 0 when they failed.
disc shell -eis now registered.disc restartcouldn’t find the instance.
Behaviour changes for upgrade notes
<datetime>casts now require a full ISO 8601 timestamp with a timezone.int / intreturnsfloat64.- Single links are typed as one-element arrays
[T]. - Bare mutations, and upserts that skip the row, return sets or
[]instead of{success: true}. - Persistent configure needs an admin.
- In the TS SDK,
decimalis typed asstring,int64asbigint, andcal::local_datetimeasstring. - When a non-default enum’s name collides with another, its PostgreSQL type is renamed to
disc_enum_<module>__<name>. NaNand±Infinityare rejected indecimalandbigint.
Full Changelog: v2026.09.25...v2026.09.28