Skip to content

v2026.09.28

Choose a tag to compare

@NetOpWibby NetOpWibby released this 29 Sep 03:50
· 14 commits to primary since this release
88f8aab

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 /query could run ALTER 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: / returns float64, // floors, % takes the divisor’s sign.
    • ^ is power.
    • and/or/not handle empty values the way Gel does.
  • 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}.
    • bigint and decimal values used to be sent as zero bytes.
    • querySingle cardinality checks.
  • Codegen and SDK:
    • Cross-module enums and same-named scalars resolve correctly.
    • int64 values come back as bigint, and datetimes (including nested ones) as Date.
    • bigint and decimal keep full precision.
    • NaN and ±Infinity work 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 -e is now registered.
    • disc restart couldn’t find the instance.

Behaviour changes for upgrade notes

  • <datetime> casts now require a full ISO 8601 timestamp with a timezone.
  • int / int returns float64.
  • 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, decimal is typed as string, int64 as bigint, and cal::local_datetime as string.
  • When a non-default enum’s name collides with another, its PostgreSQL type is renamed to disc_enum_<module>__<name>.
  • NaN and ±Infinity are rejected in decimal and bigint.

Full Changelog: v2026.09.25...v2026.09.28