Bug reference: 19470 Logged by: HaoGang Mao Email address: haogangmao@gmail.com PostgreSQL version: 18.3 Operating system: Linux Description:
Reproduction steps (minimal): BEGIN; CREATE TYPE foo AS (a int, b text); PREPARE p AS SELECT CAST(ROW(1, 'hello') AS foo)::text; EXECUTE p; ALTER TYPE foo ALTER ATTRIBUTE a TYPE VARCHAR(100); EXECUTE p; COMMIT;
Expected: Error message (type modified while a prepared plan / expression is active) Actual: Server connection dropped; backend aborts with SIGABRT due to assertion failure
Thanks for reporting and the repro, I was able to reproduce this. The cause of this crash is a cache invalidation failure. When ALTER TYPE is executed, the cached plan for the prepared statement is not properly invalidated. So the executor uses a stale memory layout during the second execution. This causes tuple deformation to see type confusion, reading a 4-byte INT as a Varlena header. The system interprets the lowest byte of the integer as a TOAST pointer, reads the adjacent garbage memory as a TOAST tag, and triggers the Assert(false) in VARTAG_SIZE, replacing the assertion with an elog(ERROR) would prevent the hard crash, it only masks the main issue. I think the correct fix is that ALTER TYPE on a composite attribute correctly triggers a plan re-validation, thoughts?