Cassandra beta2 restricts changes to partition-key types
Cassandra 4.0-beta2 refuses new fields in user-defined types referenced by partition keys. The narrower rule is more useful than the changelog shorthand about forbidding type alterations.
Adding a field to a structured value looks like an ordinary schema extension. That intuition needs qualification when the type also appears in a partition key. Cassandra 4.0-beta2 rejects adding fields to user-defined types referenced by partition-key columns. The operation now fails with an error identifying the tables that depend on the type in that position.
The release record dates beta2 to August 31, 2020. Its changelog describes CASSANDRA-15933 as forbidding alteration of UDTs used in partition keys. The implementation is more specific. The new check belongs to the operation that adds a field, so the change should not be expanded into a claim that every possible type alteration is now prohibited.
I am drawn to Cassandra for the distribution problem it solves. That makes partition-key design a substantive architectural decision to me. A restriction on extending a type used there deserves an explanation at the schema level, because the same named type can be shared across several definitions.
What the new check inspects
The beta2 type-alteration implementation first checks whether the requested field name already exists. It prepares the field type and rejects a circular reference. The new partition-key check occurs before the code constructs the updated list of field names and types.
That ordering makes rejection an explicit validation outcome. The operation does not construct an extended UDT and then discover a dependent table later in the method. It collects the dependent tables first and throws an invalid-request error if the collection is nonempty.
The search examines tables and views in the keyspace. For each one it considers partition-key columns and asks whether their column type references the UDT being changed. This is a dependency check expressed through the type system. The error includes the field being added and the UDT name, followed by the dependent table descriptions.
A named type can therefore impose a restriction at a table that is not the immediate focus of a schema change. The relevant relationship is every partition-key reference found by the search. An application cannot establish that an addition is permitted merely by inspecting one ordinary value column that uses the type.
Consider the following definitions in an existing keyspace named ks. The type has two fields, and the table uses a frozen instance as its partition key.
CREATE TYPE ks.identity_key (
tenant text,
account text
);
CREATE TABLE ks.accounts (
identity frozen<identity_key> PRIMARY KEY,
display_name text
);
The following operation asks to add a third field. In beta2, the partition-key reference causes the new validation to reject it.
ALTER TYPE ks.identity_key ADD region text;
This example illustrates the rejection path. It is not a migration recipe and does not assert that changing the type would redistribute existing data in a particular way. The source establishes the rule and the dependency search, which are sufficient to explain the changed behaviour.
General UDT evolution still has meaning
The versioned CQL type reference describes UDTs as named sets of typed fields. A type belongs to its keyspace and can be referenced by name after creation. The reference documents field addition and field renaming as separate ALTER TYPE operations.
For an allowed field addition, earlier values have null in the newly added field. That gives an ordinary value type a defined interpretation after extension. The partition-key restriction introduces a condition on whether that extension is allowed at all. The general description of older values does not override validation of the places where the type is used.
This is why the precise wording matters. A reader of the short changelog might conclude that UDTs in keys are completely immutable. The code establishes a narrower rule for new fields. Renaming has its own implementation and validation, so a statement about that operation requires reading that path separately.
The practical consequence is a dependency-aware schema change. Before considering whether existing values can represent a new null field, the server determines whether the requested addition is permitted by the current schema. The error makes the blocking dependency available to the caller.
The rest of beta2 reinforces explicit failure handling
Other beta2 entries address the handling of conditions that previously had less useful outcomes. The changelog records verification of SSTable components on startup and the use of FSWriteError for write failures so that disk-failure policy applies. It also lists improved handling of stream-session preparation errors. These entries concern different subsystems, but each identifies a concrete place where an abnormal condition must reach the appropriate decision logic.
They should not be treated as evidence that all upgrade and failure scenarios are covered. They do explain why a beta with no headline query feature still changes what operators and application authors can observe. A schema addition can now produce an immediate error with its dependencies, and a storage write failure can reach the configured disk-failure mechanism.
I prefer an explicit schema rejection to leaving the meaning of a shared key type implicit in an application convention. For beta2, the relevant rule is specific enough to review directly. Adding a field to a UDT fails when the keyspace contains a partition-key column whose type references it, and the error identifies the dependent tables.