cockroachdb / cockroachdb/cockroach
crosscluster/logical: allow CREATE UNIQUE INDEX on an LDR destination table
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Is your feature request related to a problem? Please describe.**
`IsAllowedLDRSchemaChange` (`pkg/sql/sem/tree/schema_helpers.go`) rejects
`CREATE UNIQUE INDEX` on a table that is a destination of a logical data
replication (LDR) job, on the rationale that a unique index "could cause
inserts to fail."
This is inconsistent with the rest of the system:
- **Setup does not restrict unique indexes.** A table can be made an LDR
destination while it already has unique (secondary) indexes; there is no
check at `CREATE LOGICAL REPLICATION STREAM` time that rejects them. So
unique indexes are already tolerated on destination tables — you just
can't add one after replication has started.
- **The runtime consequence is not a hard failure.** With the CRUD writer
(now the only immediate-mode writer), a replicated write that violates a
unique constraint surfaces as a `UniqueViolation` (pgcode 23505), which
is DLQ-able. The offending row is routed to the DLQ rather than failing
the job.
The net effect is a timing-dependent restriction: a unique index present
before replication is fine, but an identical index added afterward is
blocked, despite the same runtime behavior.
**Describe the solution you'd like**
Allow `CREATE UNIQUE INDEX` on an LDR destination table, consistent with
the fact that unique indexes are already permitted when present at setup
time. Conflicting replicated rows would be DLQ'd, matching existing
behavior for pre-existing unique indexes.
**Describe alternatives you've considered**
- Keep the restriction but make it consistent by also rejecting
destination tables that have unique indexes at setup time. This is more
conservative but breaks existing setups and is likely undesirable.
- Leave the asymmetry as-is (status quo). This is confusing and the
"could cause inserts to fail" rationale is stale for the CRUD writer.
**Additional context**
The check lives in `IsAllowedLDRSchemaChange`
(`pkg/sql/sem/tree/schema_helpers.go`), called from `ALTER TABLE` / schema
change validation. Note the same gate treats unique *partial* indexes
(`CREATE UNIQUE INDEX ... WHERE ...`) differently from full unique indexes,
which is part of the same inconsistency.
Epic: none
Jira issue: CRDB-65834
Contributor guide
Assessment
This issue has not been assessed yet.