Ello - Base de Conhecimentos

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

  1. Nunca subestime o tamanho de um varchar.
  2. Sempre desconfie de select * em view.
  3. Quando alterar estrutura de tabela, revise suas views e procedures.
  4. 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.