Die Besetzung ist keine echte Besetzung. Es wird nur die bequeme Syntax (ab)verwendet. Ein großes Objekt (LO) wird im Hintergrund erstellt, separat gespeichert und die darauf referenzierende OID zurückgegeben.
Die zurückgegebene OID ist im Grunde ein FK zum PK der Systemtabelle pg_largeobject
.
CREATE TABLE
ist völlig unabhängig von Funktion und Pseudocast.
CREATE TABLE bytea_to_lo (
largeObj lo
);
Es ist nur ein typischer Anwendungsfall für den oben erstellten Assignment Cast, was aus der folgenden Zeile hervorgeht, die Sie vergessen haben zu zitieren:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Was passiert hier?
Der Datentyp lo
ist eine Domäne über den Basistyp oid
, erstellt durch das Zusatzmodul lo
(fälschlicherweise als "lo_manage package" im Blog-Eintrag von Grace Batumbya
). Pro Dokumentation:
Die Funktion decode()
gibt bytea
zurück . Das INSERT
-Anweisung weist das bytea
zu Wert in die Spalte largeObj
, was eine Zuweisungsumwandlung in seinen Typ lo
auslöst , und hier kommt die obige Besetzung ins Spiel.
Warnung/Korrektur/Aktualisierung
Der Blogeintrag ist schlampig und mittlerweile veraltet.
-
Macht sich nicht die Mühe, das zu erwähnen (pro Dokumentation ). ):
Tatsächlich müssen Sie Superuser sein.
-
Tippfehler in
CREATE TABLE
:Spaltenname und Typ umgekehrt. -
Die Funktionsdefinition ist ausführlich und ineffizient. Dies wäre besser (für Postgres 9.3 oder älter):
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;
Es ist ein eingebaut Funktion dafür in Postgres 9.4 . Verwenden Sie stattdessen:
lo_from_bytea(loid oid, string bytea)
Aus den Versionshinweisen :
Für CREATE CAST
(pro Dokumentation
). ):
Ich schlage eine überladene Variante mit nur einem bytea
vor 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 der Pseudo-Cast einen ziemlich großen Nebeneffekt hat, bin ich nicht davon überzeugt, daraus eine ASSIGNMENT
zu machen gießen. Ich würde wahrscheinlich mit Explicit-only beginnen: