cockroachdb / cockroachdb/cockroach
sql: lift restriction on descriptor references in domain DEFAULT expressions
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
## Summary
Domain `DEFAULT` expressions cannot safely reference other descriptors
(sequences, functions, or user-defined types) because the type descriptor
does not yet establish back-references to those objects. Without
back-references, a referenced object can be dropped while the domain still
depends on it, leaving the domain in a broken state.
This issue tracks the multi-step plan to lift that restriction for both
`CREATE DOMAIN` and `ALTER DOMAIN ... SET DEFAULT`.
## Background
The newly added `ALTER DOMAIN ... SET DEFAULT` path in the declarative
schema changer ([PR #170773](https://github.com/cockroachdb/cockroach/pull/170773),
closing [#166935](https://github.com/cockroachdb/cockroach/issues/166935))
explicitly rejects defaults that reference sequences, functions, or UDTs.
See [alter_domain.go:137-152](https://github.com/cockroachdb/cockroach/blob/68fdd504fa76c8cb833c77a10cda093a78db1e81/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_domain.go#L137-L152):
```go
// References to other descriptors in a domain default would require
// establishing back-references from those descriptors to the domain type,
// so that the referenced object cannot be dropped while the domain still
// depends on it.
switch {
case len(expr.UsesSequenceIDs) > 0:
panic(pgerror.Newf(pgcode.FeatureNotSupported,
"sequence references in domain DEFAULT expressions are not supported"))
case len(expr.UsesFunctionIDs) > 0:
panic(pgerror.Newf(pgcode.FeatureNotSupported,
"function references in domain DEFAULT expressions are not supported"))
case len(expr.UsesTypeIDs) > 0:
panic(pgerror.Newf(pgcode.FeatureNotSupported,
"user-defined type references in domain DEFAULT expressions are not supported"))
}
```
The `CREATE DOMAIN` path in [create_type.go:618-622](https://github.com/cockroachdb/cockroach/blob/68fdd504fa76c8cb833c77a10cda093a78db1e81/pkg/sql/create_type.go#L618-L622)
does **not** have an equivalent restriction. It simply serializes the
parsed expression and stores the raw string on the descriptor without
calling `SanitizeVarFreeExpr` and without recording back-references:
```go
var defaultExpr string
if n.DomainDefault != nil {
defaultExpr = tree.Serialize(n.DomainDefault)
}
```
The result is inconsistent behavior: `ALTER DOMAIN` explicitly rejects
defaults that `CREATE DOMAIN` silently accepts (and possibly mishandles
at evaluation time, with no protection against the referenced object
being dropped).
## Resolution Plan
Three sequential parts:
### Part 1 — Fix `CREATE DOMAIN` correctness
Make `CREATE DOMAIN` type-check the default expression the same way
`ALTER DOMAIN` does (via `schemaexpr.SanitizeVarFreeExpr`) and reject
references to sequences, functions, and UDTs. This closes the
silent-acceptance gap and gives both statements consistent behavior
before any larger work begins.
### Part 2 — Implement safe back-references for domain dependencies
Establish back-references from sequences, functions, and user-defined
types into the type descriptor when a domain `DEFAULT` references them,
so the referenced object cannot be dropped while the domain still
depends on it. This mirrors how column `DEFAULT` and computed
expressions already track these dependencies on table descriptors.
### Part 3 — Lift the restriction in both paths
Once back-references are in place, remove the rejection in
`ALTER DOMAIN` and the equivalent rejection added by Part 1 in
`CREATE DOMAIN`, so domain defaults can reference sequences,
functions, and UDTs.
## Related
- PR: cockroachdb/cockroach#170773
- Closed issue: cockroachdb/cockroach#166935
Epic CRDB-66030
Jira issue: CRDB-64545
Contributor guide
Assessment
This issue has not been assessed yet.