O elenco não é um verdadeiro elenco. É apenas (ab)usando a sintaxe conveniente. Um objeto grande (LO) é criado em segundo plano que é armazenado separadamente e o OID que faz referência a ele é retornado.
Por documentação:
O OID retornado é basicamente um FK para o PK da tabela do sistema
pg_largeobject
. CRIAR TABELA
é completamente independente da função e pseudo-cast. CREATE TABLE bytea_to_lo (
largeObj lo
);
É apenas um caso de uso típico para o elenco de atribuição criado acima, que fica aparente na seguinte linha que você esqueceu de citar:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
O que acontece aqui?
O tipo de dados
lo
é um domínio sobre o tipo base oid
, criado pelo módulo adicional lo
(referenciado incorretamente como "pacote lo_manage" no entidade do blog de Grace Batumbya
). Por documentação:
A função
decode()
retorna bytea
. O INSERIR
declaração atribui o bytea
valor para a coluna largeObj
, que aciona uma conversão de atribuição para seu tipo lo
, e é aí que entra o elenco acima. Aviso/Corretivo/Atualização
A entrada do blog é desleixada e desatualizada agora.
-
Não se preocupe em mencionar isso (por documentação ):
Efetivamente, você deve ser superusuário.
-
Erro de digitação emCREATE TABLE
:nome e tipo da coluna invertidos.
-
A definição da função é detalhada e ineficiente. Isso seria melhor (para Postgres 9.3 ou mais):
CREATE OR REPLACE FUNCTION blob_write(bytea) RETURNS oid AS $func$ DECLARE loid oid := lo_create(0); lfd int := lo_open(loid,131072); -- = 2^17 = x2000 -- symbolic constant defined in the header file libpq/libpq-fs.h -- #define INV_WRITE 0x00020000 BEGIN PERFORM lowrite(lfd, $1); PERFORM lo_close(lfd); RETURN loid; END $func$ LANGUAGE plpgsql VOLATILE STRICT;
SQL Fiddle.
Há um integrado função para isso no Postgres 9.4 . Use isso em vez disso:
lo_from_bytea(loid oid, string bytea)
Das notas de versão :
Para
CREATE CAST
(por documentação
):Sugiro uma variante sobrecarregada com apenas um
bytea
parâmetro:CREATE OR REPLACE FUNCTION lo_from_bytea(bytea)
RETURNS oid LANGUAGE sql AS
'SELECT lo_from_bytea(0, $1)';
CREATE CAST (bytea AS oid) WITH FUNCTION lo_from_bytea(bytea) AS ASSIGNMENT;
Como o pseudo-cast tem um grande efeito colateral, não estou convencido de fazer disso uma
ASSIGNMENT
elenco. Eu provavelmente começaria com apenas explícito: