PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zrozumienie rzutowania od bajta do oid

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.

Według dokumentacji:

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;
    

    Skrzypce SQL.

Wbudowana jest funkcja w tym celu w Postgresie 9.4 . Użyj tego zamiast:

lo_from_bytea(loid oid, string bytea)

Z informacji o wydaniu :

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”:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHPUnit:Jak przetestować interakcje z bazą danych na zdalnym serwerze Postgres?

  2. AWS Glue - Obcinanie docelowej tabeli postgres przed wstawieniem

  3. Jak zredukować liczbę połączeń za pomocą SQLAlchemy + postgreSQL?

  4. W migracji Rails, jak ustawić domyślną wartość kolumny na NOW() zamiast czasu uruchomienia migracji?

  5. Zapytanie według współrzędnych trwa zbyt długo - opcje do optymalizacji?