De cast is geen echte cast. Het is gewoon (ab)gebruiken van de handige syntaxis. Een groot object (LO) wordt op de achtergrond gemaakt die afzonderlijk wordt opgeslagen en de OID die ernaar verwijst, wordt geretourneerd.
De geretourneerde OID is in feite een FK voor de PK van de systeemtabel pg_largeobject
.
CREATE TABLE
is volledig onafhankelijk van de functie en pseudo-cast.
CREATE TABLE bytea_to_lo (
largeObj lo
);
Het is gewoon een typische use-case voor de hierboven gemaakte opdrachtcast, wat blijkt uit de volgende regel die u bent vergeten te citeren:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Wat gebeurt hier?
Het gegevenstype lo
is een domein boven het basistype oid
, gemaakt door de aanvullende module lo
(ten onrechte naar "lo_manage-pakket" verwezen in de blog van Grace Batumbya
). Per documentatie:
De functie decode()
retourneert bytea
. De INSERT
statement wijst de bytea
. toe waarde naar de kolom largeObj
, die een toewijzing activeert naar het type lo
, en dat is waar de bovenstaande cast van pas komt.
Waarschuwing / Corrigerende / Update
Het blogbericht is inmiddels slordig en verouderd.
-
Neemt niet de moeite om dat te vermelden (per documentatie ):
In feite moet u een supergebruiker zijn.
-
Typfout in
CREATE TABLE
:kolomnaam en type omgekeerd. -
De functiedefinitie is uitgebreid en inefficiënt. Dit zou beter zijn (voor Postgres 9.3 of ouder):
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;
Er is een ingebouwd functie hiervoor in Postgres 9.4 . Gebruik dat in plaats daarvan:
lo_from_bytea(loid oid, string bytea)
Uit de release-opmerkingen :
Voor CREATE CAST
(per documentatie
):
Ik stel een overbelaste variant voor met alleen een 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;
Aangezien de pseudo-cast nogal een groot neveneffect heeft, ben ik er niet van overtuigd om daar een ASSIGNMENT
van te maken. vorm. Ik zou waarschijnlijk beginnen met alleen expliciet: