Le casting n'est pas un vrai casting. C'est juste (ab) en utilisant la syntaxe pratique. Un grand objet (LO) est créé en arrière-plan qui est stocké séparément et l'OID qui y fait référence est renvoyé.
L'OID renvoyé est essentiellement un FK au PK de la table système pg_largeobject
.
CREATE TABLE
est complètement indépendant de la fonction et du pseudo-cast.
CREATE TABLE bytea_to_lo (
largeObj lo
);
Il s'agit simplement d'un cas d'utilisation typique du casting d'affectation créé ci-dessus, qui ressort de la ligne suivante que vous avez oublié de citer :
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Que se passe-t-il ici ?
Le type de données lo
est un domaine sur le type de base oid
, créé par le module supplémentaire lo
(incorrectement référencé comme "paquet lo_manage" dans le blog de Grace Batumbya
). Par documentation :
La fonction decode()
renvoie bytea
. Le INSERT
l'instruction attribue le bytea
valeur à la colonne largeObj
, qui déclenche une affectation convertie en son type lo
, et c'est là que le casting ci-dessus entre en jeu.
Avertissement / Correctif / Mise à jour
L'entrée de blog est bâclée et obsolète à présent.
-
Ne prend pas la peine de le mentionner (par documentation ):
En effet, vous devez être superutilisateur.
-
Faute de frappe dans
CREATE TABLE
:nom et type de colonne inversés. -
La définition de la fonction est verbeuse et inefficace. Ce serait mieux (pour Postgres 9.3 ou plus ancien) :
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;
Il y a un intégré fonction pour cela dans Postgres 9.4 . Utilisez-le à la place :
lo_from_bytea(loid oid, string bytea)
À partir des notes de version :
Pour CREATE CAST
(par documentation
):
Je suggère une variante surchargée avec seulement un bytea
paramètre :
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;
Étant donné que le pseudo-cast a un effet secondaire assez important, je ne suis pas convaincu d'en faire une ASSIGNMENT
moulage. Je commencerais probablement par explicite uniquement :