Obsada nie jest prawdziwą obsadą. To tylko (nad)używanie wygodnej składni. duży obiekt (LO) jest tworzony w tle, który jest przechowywany oddzielnie, a OID, do którego się odnosi, jest zwracany.
Zwrócony OID jest w zasadzie FK do PK tabeli systemowej pg_largeobject
.
UTWÓRZ TABELĘ
jest całkowicie niezależny od funkcji i pseudo-castu.
CREATE TABLE bytea_to_lo (
largeObj lo
);
To tylko typowy przypadek użycia dla przypisania utworzonego powyżej, co wynika z poniższego wiersza, którego zapomniałeś zacytować:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
Co się tutaj dzieje?
Typ danych lo
jest domeną nad typem podstawowym oid
, utworzony przez dodatkowy moduł lo
(nieprawidłowo określany jako „lo_manage package” w Blog Grace Batumbya
). Zgodnie z dokumentacją:
Funkcja decode()
zwraca bajta
. WSTAW
instrukcja przypisuje bytea
wartość do kolumny largeObj
, który uruchamia przypisanie rzutowane na jego typ lo
, i tu właśnie pojawia się powyższa obsada.
Ostrzeżenie/Korekta/Aktualizacja
Wpis na blogu jest już niestaranny i nieaktualny.
-
Nie zadaje sobie trudu, aby o tym wspomnieć (w dokumentacji ):
W rzeczywistości musisz być superużytkownikiem.
-
Literówka w
CREATE TABLE
:odwrócona nazwa i typ kolumny. -
Definicja funkcji jest pełna i nieefektywna. Byłoby lepiej (dla Postgresa 9.3 lub starszy):
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;
Wbudowana jest funkcja w tym celu w Postgresie 9.4 . Użyj tego zamiast:
lo_from_bytea(loid oid, string bytea)
Dla UTWÓRZ PRZESYŁANIE
(zgodnie z dokumentacją
):
Proponuję przeładowany wariant z tylko bajtem
parametr:
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;
Ponieważ pseudo-cast ma dość duży efekt uboczny, nie jestem przekonany, aby uczynić z tego ZADANIE
rzucać. Prawdopodobnie zacząłbym od „tylko jawne”: