Rollebesætningen er ikke en ægte rollebesætning. Det er bare at (misbruge) den praktiske syntaks. Et stort objekt (LO) oprettes i baggrunden, som gemmes separat, og den OID, der refererer til den, returneres.
Det returnerede OID er dybest set en FK til PK i systemtabellen pg_largeobject
.
OPRET TABEL
er fuldstændig uafhængig af funktionen og pseudo-castet.
CREATE TABLE bytea_to_lo (
largeObj lo
);
Det er bare en typisk use case for opgavebesætningen oprettet ovenfor, hvilket fremgår af følgende linje, som du glemte at citere:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Hvad sker der her?
Datatypen lo
er et domæne over basistypen oid
, oprettet af det ekstra modul lo
(forkert omtalt som "lo_manage-pakke" i Blogenty af Grace Batumbya
). Pr. dokumentation:
Funktionen decode()
returnerer bytea
. INSERT
sætningen tildeler bytea
værdi til kolonnen largeObj
, som udløser en opgave cast til dens type lo
, og det er her, ovenstående rollebesætning kommer ind.
Advarsel / Korrigerende / Opdatering
Blogindlægget er sjusket og forældet efterhånden.
-
Gider ikke nævne det (pr. dokumentation ):
Faktisk skal du være superbruger.
-
Skrivefejl i
CREATE TABLE
:kolonnenavn og type omvendt. -
Funktionsdefinitionen er omfattende og ineffektiv. Dette ville være bedre (for Postgres 9.3 eller ældre):
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;
Der er en indbygget funktion for dette i Postgres 9.4 . Brug det i stedet:
lo_from_bytea(loid oid, string bytea)
Fra udgivelsesbemærkningerne :
For CREATE CAST
(pr. dokumentation
):
Jeg foreslår en overbelastet variant med kun en bytea
parameter:
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;
Da pseudo-castet har en ret stor bivirkning, er jeg ikke overbevist om at gøre det til en OPDRAGELSE
støbt. Jeg ville nok starte med kun eksplicit: