El elenco no es un verdadero elenco. Es solo (ab) usar la sintaxis conveniente. Un objeto grande (LO) se crea en segundo plano, que se almacena por separado y se devuelve el OID que hace referencia a él.
El OID devuelto es básicamente un FK al PK de la tabla del sistema pg_largeobject
.
CREATE TABLE
es completamente independiente de la función y pseudo-cast.
CREATE TABLE bytea_to_lo (
largeObj lo
);
Es solo un caso de uso típico para el modelo de asignación creado anteriormente, que se hace evidente en la siguiente línea que olvidó citar:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
¿Qué sucede aquí?
El tipo de datos lo
es un dominio sobre el tipo base oid
, creado por el módulo adicional lo
(incorrectamente mencionado como "paquete lo_manage" en entidad del blog de Grace Batumbya
). Por documentación:
La función decode()
devuelve bytea
. El INSERT
sentencia asigna el bytea
valor a la columna largeObj
, que desencadena una conversión de asignación a su tipo lo
, y ahí es donde entra en juego el elenco anterior.
Advertencia/Corrección/Actualización
La entrada del blog está descuidada y desactualizada por ahora.
-
No se molesta en mencionar que (por documentación ):
Efectivamente, debes ser superusuario.
-
Error tipográfico en
CREATE TABLE
:nombre de columna y tipo invertidos. -
La definición de la función es detallada e ineficiente. Esto sería mejor (para Postgres 9.3 o mayor):
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;
Hay un incorporado función para esto en Postgres 9.4 . Usa eso en su lugar:
lo_from_bytea(loid oid, string bytea)
De las notas de la versión :
Para CREATE CAST
(según documentación
):
Sugiero una variante sobrecargada con solo un bytea
parámetro:
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;
Dado que el pseudo-cast tiene un efecto secundario bastante grande, no estoy convencido de hacer de eso una ASSIGNMENT
emitir. Probablemente comenzaría con solo explícito: