Dados los siguientes comandos:
create table foo(id serial primary key); insert into foo values (1), (2), (3), (4); alter table foo add column bar integer not null default 10; alter table foo alter column bar drop default; Cuando ejecuto select * from foo; Yo obtengo:
id | bar ----+------ 1 | 10 2 | 10 3 | 10 4 | 10¿Cómo es esto posible si a partir de postgresql 11+, evalúa los valores predeterminados no nulos de forma perezosa?
Los valores predeterminados de columna se almacenan en el catálogo del sistema pg_attrdef , mientras que las definiciones de columna se almacenan en pg_attribute . Si descarta el valor predeterminado, se elimina la fila pg_attrdef , pero no la fila pg_attribute .
El secreto detrás de lo que observa es que el "valor de atributo faltante" se almacena en pg_attribute , por lo que no se ve afectado:
SELECT attmissingval FROM pg_attribute WHERE attrelid = 'foo'::regclass AND attname = 'bar'; attmissingval ═══════════════ {10} (1 row)Desglosando cada declaración alter:
alter table foo add column bar integer not null default 10 Esto agrega la nueva columna, y debido a que not null default 10 , cada fila recibe 10 para el valor de la columna.
En este punto, todas las filas existentes tienen 10 y todas las filas futuras recibirán 10 si no se proporciona un valor en la inserción.
alter table foo alter column bar drop default Esto no afecta las filas existentes. Solo afecta las filas futuras que se insertan, ahora requiere un valor porque la restricción not null permanece, pero el valor predeterminado no.