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.