PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ottieni la dimensione di un oggetto di grandi dimensioni nella query di PostgreSQL?

Non che io abbia usato oggetti di grandi dimensioni, ma guardando i documenti:http://www.postgresql.org/docs/current/interactive/lo-interfaces.html#LO-TELL

Penso che tu debba usare la stessa tecnica richiesta da alcune API del file system:cerca fino alla fine, quindi indica la posizione. PostgreSQL ha funzioni SQL che sembrano racchiudere le funzioni C interne. Non sono riuscito a trovare molta documentazione, ma ha funzionato:

CREATE OR REPLACE FUNCTION get_lo_size(oid) RETURNS bigint
VOLATILE STRICT
LANGUAGE 'plpgsql'
AS $$
DECLARE
    fd integer;
    sz bigint;
BEGIN
    -- Open the LO; N.B. it needs to be in a transaction otherwise it will close immediately.
    -- Luckily a function invocation makes its own transaction if necessary.
    -- The mode x'40000'::int corresponds to the PostgreSQL LO mode INV_READ = 0x40000.
    fd := lo_open($1, x'40000'::int);
    -- Seek to the end.  2 = SEEK_END.
    PERFORM lo_lseek(fd, 0, 2);
    -- Fetch the current file position; since we're at the end, this is the size.
    sz := lo_tell(fd);
    -- Remember to close it, since the function may be called as part of a larger transaction.
    PERFORM lo_close(fd);
    -- Return the size.
    RETURN sz;
END;
$$; 

Testandolo:

-- Make a new LO, returns an OID e.g. 1234567
SELECT lo_create(0);

-- Populate it with data somehow
...

-- Get the length.
SELECT get_lo_size(1234567);

Sembra che la funzionalità LO sia progettata per essere utilizzata principalmente tramite il client o tramite la programmazione del server di basso livello, ma almeno hanno fornito alcune funzioni SQL visibili per essa, il che rende possibile quanto sopra. Ho fatto una query per SELECT relname FROM pg_proc where relname LIKE 'lo%' per iniziare me stesso. Vaghi ricordi di programmazione in C e un po' di ricerca per la modalità x'40000'::int e SEEK_END = 2 il valore era necessario per il resto!