application opens a new large object, seeks to offset
1000000, and writes a few bytes there, this does not result in allocation
of 1000000 bytes worth of storage; only of chunks covering the range of
data bytes actually written. A read operation will, however, read out
zeroes for any unallocated locations preceding the last existing chunk.
This corresponds to the common behavior of <quote>sparsely allocated</quote>
files in <acronym>Unix</acronym> file systems.
</para>
<para>
As of <productname>PostgreSQL</productname> 9.0, large objects have an owner
and a set of access permissions, which can be managed using
<xref linkend="sql-grant"/> and
<xref linkend="sql-revoke"/>.
<literal>SELECT</literal> privileges are required to read a large
object, and
<literal>UPDATE</literal> privileges are required to write or
truncate it.
Only the large object's owner (or a database superuser) can delete,
comment on, or change the owner of a large object.
To adjust this behavior for compatibility with prior releases, see the
<xref linkend="guc-lo-compat-privileges"/> run-time parameter.
</para>
</sect1>
<sect1 id="lo-interfaces">
<title>Client Interfaces</title>
<para>
This section describes the facilities that
<productname>PostgreSQL</productname>'s <application>libpq</application>
client interface library provides for accessing large objects.
The <productname>PostgreSQL</productname> large object interface is
modeled after the <acronym>Unix</acronym> file-system interface, with
analogues of <function>open</function>, <function>read</function>,
<function>write</function>,
<function>lseek</function>, etc.
</para>
<para>
All large object manipulation using these functions
<emphasis>must</emphasis> take place within an SQL transaction block,
since large object file descriptors are only valid for the duration of
a transaction. Write operations, including <function>lo_open</function>
with the <symbol>INV_WRITE</symbol> mode, are not allowed in a read-only
transaction.
</para>
<para>
If an error occurs while executing any one of these functions, the
function will return an otherwise-impossible value, typically 0 or -1.
A message describing the error is stored in the connection object and
can be retrieved with <xref linkend="libpq-PQerrorMessage"/>.
</para>
<para>
Client applications that use these functions should include the header file
<filename>libpq/libpq-fs.h</filename> and link with the
<application>libpq</application> library.
</para>
<para>
Client applications cannot use these functions while a libpq connection is in pipeline mode.
</para>
<sect2 id="lo-create">
<title>Creating a Large Object</title>
<para>
<indexterm><primary>lo_create</primary></indexterm>
The function
<synopsis>
Oid lo_create(PGconn *conn, Oid lobjId);
</synopsis>
creates a new large object. The OID to be assigned can be
specified by <replaceable class="parameter">lobjId</replaceable>;
if so, failure occurs if that OID is already in use for some large
object. If <replaceable class="parameter">lobjId</replaceable>
is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</function>
assigns an unused OID.
The return value is the OID that was assigned to the new large object,
or <symbol>InvalidOid</symbol> (zero) on failure.
</para>
<para>
An example:
<programlisting>
inv_oid = lo_create(conn, desired_oid);
</programlisting>
</para>
<para>
<indexterm><primary>lo_creat</primary></indexterm>
The older function
<synopsis>
Oid lo_creat(PGconn *conn, int mode);
</synopsis>
also creates a new large object, always assigning an unused OID.
The return value is the OID that was assigned to the new large object,
or <symbol>InvalidOid</symbol> (zero) on failure.