~~NOTOC~~ ====== Quando o Fenômeno quebra a view: uma crônica sobre o Firebird ====== Todo desenvolvedor raiz já passou por isso: você cria uma tabelinha inocente, insere uns dados camaradas, faz um ''commit'' com aquele sentimento de dever cumprido… e cinco minutos depois está olhando para uma mensagem de erro como se ela tivesse ofendido a sua família. Hoje, nosso protagonista não é um bug obscuro nem uma corrupção de índice mística. É algo muito mais sutil: uma **limitação comportamental** do nosso querido Firebird. E para ilustrar, convocamos ninguém menos que a Seleção de 94. \\ ===== Escalando o time ===== Começamos com uma tabela humilde: create table selecao_brasileira_94 ( num_camisa integer not null, nome varchar(8), posicao varchar(16), constraint jogadores_pk primary key (num_camisa) ); Repare no detalhe aparentemente inofensivo: ''nome varchar(8)''. Oito caracteres. Oito. Na nossa cabeça, isso era mais que suficiente. Afinal, temos: * Taffarel * Jorginho * Bebeto * Romário * Zetti Tudo cabe. Tudo bonito. O ''select'' confirma: a base está mais organizada que concentração antes de final de Copa. \\ ===== A view marota ===== Como bons profissionais organizados, decidimos criar uma ''view'' para facilitar a vida quando quisermos listar apenas os atacantes: create view vw_atacantes as select * from selecao_brasileira_94 where posicao='Atacante'; Testamos: 7 Bebeto Atacante 11 Romário Atacante Perfeito. Clean. Elegante. Arquitetura digna de Tetra. \\ ===== Entra o Fenômeno ===== Mas aí percebemos um erro histórico gravíssimo: esquecemos do Ronaldo. Tentamos inserir: insert into selecao_brasileira_94 values (20, 'Ronaldo Fenômeno', 'Atacante'); E o Firebird responde com aquele carinho: arithmetic exception, numeric overflow, or string truncation -string right truncation Tradução: “Meu amigo, você me prometeu 8 caracteres. Isso aí é um parágrafo.” Justo. Então fazemos o que qualquer adulto funcional faria: alter table selecao_brasileira_94 alter nome type varchar(16); Agora cabe o Fenômeno inteiro. Inserimos novamente. ''commit''. Tudo certo. \\ ===== O momento da traição ===== Consultamos a tabela: 20 Ronaldo Fenômeno Atacante Lindo. Funcionando. Maravilhoso. Aí vamos testar nossa view ''vw_atacantes''... E o Firebird solta: 11 Romário Atacante Statement failed... -string right truncation Desculpa, o quê? **string truncation**? seria algo relacionado a PlayStation?! Mas… nós já aumentamos o campo para ''varchar(16)''! Sim. A tabela está feliz. Mas a view… está presa em 1994. \\ ===== O que aconteceu de verdade? ===== Aqui está o ponto técnico — e a limitação ilustrada. No Firebird, a ''view'' materializa (em termos de metadados) a estrutura das colunas no momento da sua criação. Quando você faz: create view vw_atacantes as select * from selecao_brasileira_94 ... O Firebird registra que: nome = varchar(8) Mesmo que depois você altere a tabela para ''varchar(16)'', a view continua acreditando que o mundo é um lugar onde nomes têm no máximo 8 caracteres. Ela não “herda dinamicamente” a nova definição. Resultado: quando o Ronaldo entra em campo, a view tenta encaixá-lo em 8 caracteres. E ninguém coloca o Fenômeno numa caixa de 8 caracteres. \\ ===== Por que isso acontece? ===== Porque no Firebird a definição de view não é apenas um “ponteiro para o SELECT”. Ela mantém metadados próprios das colunas resultantes. Alterou tipo de coluna na tabela base? A view (ou procedure) não é automaticamente recompilada. Você precisa: drop view vw_atacantes; E depois: create view vw_atacantes as ... Ou usar ''CREATE OR ALTER VIEW''. \\ ===== Moral da história ===== - Nunca subestime o tamanho de um ''varchar''. - Sempre desconfie de ''select *'' em view. - Quando alterar estrutura de tabela, revise suas views e procedures. - E principalmente: nunca tente truncar o Fenômeno. \\ ===== Conclusão ===== Esse comportamento não é exatamente um bug — é uma característica arquitetural do Firebird. Ele preserva metadados da view no momento da criação, o que pode levar a inconsistências quando a estrutura base muda. É o tipo de detalhe que só aparece quando você mistura: * alteração de schema * ''select *'' * e um atacante com nome composto Ou seja: praticamente inevitável. Se 1994 nos ensinou que o Brasil é gigante, o Firebird nos ensina que ''varchar(8)'' não é. E que toda view tem memória. Mesmo que você não tenha.