A documentação do Postgresql é clara neste ponto: você não pode alterar as colunas de uma visão existente.
A nova consulta deve gerar as mesmas colunas que foram geradas pela consulta de exibição existente (ou seja, os mesmos nomes de coluna na mesma ordem e com os mesmos tipos de dados) (...)
Referência: http://www.postgresql.org/docs/9.3/static/sql-createview.html
Por que diabos eu tenho que DROP a exibição ou ALTER para modificá-la?
É uma limitação de implementação. É teoricamente possível, claro, mas ninguém escreveu o código para lidar com isso ainda.
Para lidar com remoções de colunas ou mudanças de tipo, o PostgreSQL teria que verificar todas as visualizações que fazem referência à visualização que está sendo modificada (usando
pg_catalog.pg_depend
) para ver se alguma delas depende da coluna. Também seria necessário procurar referências de linha inteira e proibir alterações nesses casos.É menos claro por que não é permitido adicionar uma coluna. Mais uma vez, suspeito que isso se deva a referências de linha inteira. Se
pg_depend
foi verificado referências de linhas inteiras sem encontrar nenhuma e a nova coluna apareceu no final, não há problema em adicioná-la.No entanto, as exibições criadas com
SELECT * FROM
não "herdariam" a nova coluna, porque*
são expandidas em uma lista de colunas durante a criação da exibição. Portanto, se você tivesseview_A
umSELECT * FROM view_B
e adicionasse uma coluna aview_B
, ela não apareceria emview_A
. No entanto, se você descartasse e recriasseview_A
, a coluna apareceria. Escusado será dizer que isso não é bom. Para lidar com isso, o PostgreSQL teria que monitorar se a lista de colunas de uma determinada visão ("targetlist" em termos internos do PostgreSQL) veio de um*
curinga. O que é mais complicado do que você pensa, porque vocêsomeview.*
também sabe escrever.Em suma - é complicado e ninguém o queria o suficiente para fazer o trabalho de implementá-lo.