Il cast non è un vero cast. Sta solo (ab)usando la comoda sintassi. Un oggetto grande (LO) viene creato in background che viene memorizzato separatamente e viene restituito l'OID di riferimento.
L'OID restituito è fondamentalmente un FK per il PK della tabella di sistema pg_largeobject
.
CREATE TABLE
è completamente indipendente dalla funzione e pseudocast.
CREATE TABLE bytea_to_lo (
largeObj lo
);
È solo un tipico caso d'uso per il cast di assegnazione creato sopra, che diventa evidente dalla seguente riga che hai dimenticato di citare:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Cosa succede qui?
Il tipo di dati lo
è un dominio sul tipo di base oid
, creato dal modulo aggiuntivo lo
(indicato erroneamente come "pacchetto lo_manage" in blog entità di Grace Batumbya
). Per documentazione:
La funzione decode()
restituisce bytea
. Il INSERT
assegna il bytea
valore alla colonna largeObj
, che attiva un cast di assegnazione al suo tipo lo
, ed è qui che entra in gioco il cast di cui sopra.
Avviso/Correzione/Aggiornamento
Il post del blog è sciatto e ormai obsoleto.
-
Non si preoccupa di menzionarlo (per documentazione ):
In effetti, devi essere superutente.
-
Errore di battitura in
CREATE TABLE
:nome e tipo della colonna invertiti. -
La definizione della funzione è dettagliata e inefficiente. Sarebbe meglio (per Postgres 9.3 o più vecchi):
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;
Esiste un integrato funzione per questo in Postgres 9.4 . Usa quello invece:
lo_from_bytea(loid oid, string bytea)
Dalle note sulla versione :
Per CREATE CAST
(per documentazione
):
Suggerisco una variante sovraccarica con solo un bytea
parametro:
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;
Dal momento che lo pseudo-cast ha un effetto collaterale piuttosto grande, non sono convinto di renderlo un ASSIGNMENT
lancio. Probabilmente inizierei con solo esplicito: