head	1.55;
access;
symbols
	REL9_0_0:1.53.2.2
	REL9_1_ALPHA1:1.55
	REL9_0_RC1:1.53.2.2
	REL9_0_BETA4:1.53
	REL9_0_STABLE:1.53.0.2
	REL9_0_BETA3:1.53
	REL9_0_BETA2:1.53
	REL7_4_29:1.31.2.1
	REL8_0_25:1.36
	REL8_1_21:1.37.2.1
	REL8_2_17:1.42
	REL8_3_11:1.46
	REL8_4_4:1.49
	REL9_0_BETA1:1.53
	REL9_0_ALPHA5_BRANCH:1.52.0.4
	REL9_0_ALPHA5:1.52
	REL7_4_28:1.31.2.1
	REL8_0_24:1.36
	REL8_1_20:1.37.2.1
	REL8_2_16:1.42
	REL8_3_10:1.46
	REL8_4_3:1.49
	REL9_0_ALPHA4:1.52
	REL9_0_ALPHA4_BRANCH:1.52.0.2
	REL8_5_ALPHA3:1.51
	REL8_5_ALPHA3_BRANCH:1.51.0.2
	REL7_4_27:1.31.2.1
	REL8_0_23:1.36
	REL8_1_19:1.37.2.1
	REL8_2_15:1.42
	REL8_3_9:1.46
	REL8_4_2:1.49
	REL8_5_ALPHA2:1.49
	REL8_5_ALPHA2_BRANCH:1.49.0.6
	REL7_4_26:1.31.2.1
	REL8_0_22:1.36
	REL8_1_18:1.37.2.1
	REL8_2_14:1.42
	REL8_3_8:1.46
	REL8_4_1:1.49
	REL8_5_ALPHA1:1.49
	REL8_5_ALPHA1_BRANCH:1.49.0.4
	REL8_4_STABLE:1.49.0.2
	REL8_4_0:1.49
	REL8_4_RC2:1.49
	REL8_4_RC1:1.49
	REL8_4_BETA2:1.49
	REL8_4_BETA1:1.49
	REL7_4_25:1.31.2.1
	REL8_0_21:1.36
	REL8_1_17:1.37.2.1
	REL8_2_13:1.42
	REL8_3_7:1.46
	REL7_4_24:1.31.2.1
	REL8_0_20:1.36
	REL8_1_16:1.37.2.1
	REL8_2_12:1.42
	REL8_3_6:1.46
	REL7_4_23:1.31.2.1
	REL8_0_19:1.36
	REL8_1_15:1.37.2.1
	REL8_2_11:1.42
	REL8_3_5:1.46
	REL7_4_22:1.31.2.1
	REL8_0_18:1.36
	REL8_1_14:1.37.2.1
	REL8_2_10:1.42
	REL8_3_4:1.46
	REL7_4_21:1.31.2.1
	REL8_0_17:1.36
	REL8_1_13:1.37.2.1
	REL8_2_9:1.42
	REL8_3_3:1.46
	REL7_4_20:1.31.2.1
	REL8_0_16:1.36
	REL8_1_12:1.37.2.1
	REL8_2_8:1.42
	REL8_3_2:1.46
	REL8_2_7:1.42
	REL8_3_1:1.46
	REL8_3_STABLE:1.46.0.2
	REL8_3_0:1.46
	REL8_3_RC2:1.46
	REL7_3_21:1.27
	REL7_4_19:1.31.2.1
	REL8_0_15:1.36
	REL8_1_11:1.37.2.1
	REL8_2_6:1.42
	REL8_3_RC1:1.46
	REL8_3_BETA4:1.46
	REL8_3_BETA3:1.46
	REL8_3_BETA2:1.46
	REL8_3_BETA1:1.46
	REL7_3_20:1.27
	REL7_4_18:1.31.2.1
	REL8_0_14:1.36
	REL8_1_10:1.37.2.1
	REL8_2_5:1.42
	REL7_3_19:1.27
	REL7_4_17:1.31.2.1
	REL8_0_13:1.36
	REL8_1_9:1.37.2.1
	REL8_2_4:1.42
	REL8_0_12:1.36
	REL8_1_8:1.37.2.1
	REL8_2_3:1.42
	REL7_3_18:1.27
	REL7_4_16:1.31.2.1
	REL8_0_11:1.36
	REL8_1_7:1.37.2.1
	REL8_2_2:1.42
	REL8_0_10:1.36
	REL8_1_6:1.37.2.1
	REL8_2_1:1.42
	REL7_4_15:1.31.2.1
	REL7_3_17:1.27
	REL8_2_STABLE:1.42.0.2
	REL8_2_0:1.42
	REL8_2_RC1:1.42
	REL8_2_BETA3:1.42
	REL8_2_BETA2:1.42
	REL8_1_5:1.37.2.1
	REL8_0_9:1.36
	REL7_4_14:1.31.2.1
	REL7_3_16:1.27
	REL8_2_BETA1:1.41
	REL7_3_15:1.27
	REL7_4_13:1.31.2.1
	REL8_0_8:1.36
	REL8_1_4:1.37.2.1
	REL7_3_14:1.27
	REL7_4_12:1.31.2.1
	REL8_0_7:1.36
	REL8_1_3:1.37
	REL7_3_13:1.27
	REL7_4_11:1.31.2.1
	REL8_0_6:1.36
	REL8_1_2:1.37
	REL7_3_12:1.27
	REL7_4_10:1.31.2.1
	REL8_0_5:1.36
	REL8_1_1:1.37
	REL8_1_STABLE:1.37.0.2
	REL8_1_0:1.37
	REL8_1_0RC1:1.37
	REL8_1_0BETA4:1.37
	REL8_1_0BETA3:1.37
	REL7_3_11:1.27
	REL7_4_9:1.31.2.1
	REL8_0_4:1.36
	REL8_1_0BETA2:1.37
	REL8_1_0BETA1:1.37
	REL7_2_8:1.26
	REL7_3_10:1.27
	REL7_4_8:1.31.2.1
	REL8_0_3:1.36
	REL8_0_2:1.36
	REL7_2_7:1.26
	REL7_3_9:1.27
	REL7_4_7:1.31.2.1
	REL8_0_1:1.36
	REL8_0_STABLE:1.36.0.4
	REL8_0_0:1.36.0.2
	REL8_0_0RC5:1.36
	REL8_0_0RC4:1.34
	REL8_0_0RC3:1.34
	REL8_0_0RC2:1.33
	REL8_0_0RC1:1.33
	REL8_0_0BETA5:1.33
	REL8_0_0BETA4:1.33
	REL7_4_6:1.31.2.1
	REL7_3_8:1.27
	REL7_2_6:1.26
	REL8_0_0BETA3:1.33
	REL8_0_0BETA2:1.33
	REL7_2_5:1.26
	REL7_4_5:1.31.2.1
	REL7_3_7:1.27
	REL7_4_4:1.31.2.1
	REL8_0_0BETA1:1.33
	REL7_4_3:1.31.2.1
	REL7_4_2:1.31.2.1
	REL7_3_6:1.27
	REL7_4_1:1.31.2.1
	REL7_3_5:1.27
	REL7_4:1.31.2.1
	REL7_4_RC2:1.31
	REL7_4_STABLE:1.31.0.2
	REL7_4_RC1:1.31
	REL7_4_BETA5:1.30
	REL7_4_BETA4:1.30
	REL7_4_BETA3:1.30
	REL7_4_BETA2:1.29
	WIN32_DEV:1.29.0.2
	REL7_4_BETA1:1.29
	REL7_3_4:1.27
	REL7_3_2:1.27
	REL7_2_4:1.26
	REL7_3_STABLE:1.27.0.2
	REL7_2_3:1.26
	REL7_2_STABLE:1.26.0.2
	REL7_2:1.26
	REL7_2_RC2:1.26
	REL7_2_RC1:1.26
	REL7_2_BETA5:1.25
	REL7_2_BETA4:1.24
	REL7_2_BETA3:1.24
	REL7_2_BETA2:1.23
	REL7_2_BETA1:1.23
	REL7_1_2:1.16
	REL7_1_STABLE:1.16.0.2
	REL7_1_BETA:1.13
	REL7_1_BETA3:1.14
	REL7_1_BETA2:1.14
	REL7_1:1.16
	REL7_0_PATCHES:1.12.0.2
	REL7_0:1.11
	REL6_5_PATCHES:1.6.0.2
	REL6_5:1.6
	REL6_4:1.3.0.2
	release-6-3:1.1;
locks; strict;
comment	@# @;


1.55
date	2010.08.10.02.56.46;	author rhaas;	state Exp;
branches;
next	1.54;

1.54
date	2010.08.09.12.00.24;	author rhaas;	state Exp;
branches;
next	1.53;

1.53
date	2010.04.03.07.22.55;	author petere;	state Exp;
branches
	1.53.2.1;
next	1.52;

1.52
date	2010.02.17.04.19.37;	author tgl;	state Exp;
branches;
next	1.51;

1.51
date	2009.12.17.14.36.16;	author rhaas;	state Exp;
branches;
next	1.50;

1.50
date	2009.12.11.03.34.55;	author itagaki;	state Exp;
branches;
next	1.49;

1.49
date	2008.12.07.23.46.39;	author alvherre;	state Exp;
branches
	1.49.2.1;
next	1.48;

1.48
date	2008.03.22.01.55.14;	author ishii;	state Exp;
branches;
next	1.47;

1.47
date	2008.03.19.00.39.33;	author ishii;	state Exp;
branches;
next	1.46;

1.46
date	2007.03.14.00.15.26;	author tgl;	state Exp;
branches;
next	1.45;

1.45
date	2007.03.03.19.52.45;	author momjian;	state Exp;
branches;
next	1.44;

1.44
date	2007.02.01.19.10.24;	author momjian;	state Exp;
branches;
next	1.43;

1.43
date	2007.01.31.20.56.17;	author momjian;	state Exp;
branches;
next	1.42;

1.42
date	2006.10.23.18.10.31;	author petere;	state Exp;
branches;
next	1.41;

1.41
date	2006.09.16.00.30.14;	author momjian;	state Exp;
branches;
next	1.40;

1.40
date	2006.04.23.03.39.52;	author momjian;	state Exp;
branches;
next	1.39;

1.39
date	2006.03.10.19.10.48;	author momjian;	state Exp;
branches;
next	1.38;

1.38
date	2006.03.02.21.49.09;	author tgl;	state Exp;
branches;
next	1.37;

1.37
date	2005.06.13.02.26.46;	author tgl;	state Exp;
branches
	1.37.2.1;
next	1.36;

1.36
date	2005.01.10.00.04.38;	author tgl;	state Exp;
branches;
next	1.35;

1.35
date	2005.01.08.22.13.33;	author tgl;	state Exp;
branches;
next	1.34;

1.34
date	2004.12.28.22.47.15;	author tgl;	state Exp;
branches;
next	1.33;

1.33
date	2003.11.29.19.51.37;	author pgsql;	state Exp;
branches;
next	1.32;

1.32
date	2003.11.12.22.47.47;	author petere;	state Exp;
branches;
next	1.31;

1.31
date	2003.11.01.01.56.29;	author petere;	state Exp;
branches
	1.31.2.1;
next	1.30;

1.30
date	2003.08.31.17.32.19;	author petere;	state Exp;
branches;
next	1.29;

1.29
date	2003.06.21.21.51.33;	author tgl;	state Exp;
branches
	1.29.2.1;
next	1.28;

1.28
date	2003.03.13.01.30.28;	author petere;	state Exp;
branches;
next	1.27;

1.27
date	2002.04.18.14.28.14;	author momjian;	state Exp;
branches;
next	1.26;

1.26
date	2002.01.20.22.19.56;	author petere;	state Exp;
branches;
next	1.25;

1.25
date	2002.01.07.02.29.12;	author petere;	state Exp;
branches;
next	1.24;

1.24
date	2001.11.12.19.19.39;	author petere;	state Exp;
branches;
next	1.23;

1.23
date	2001.10.09.18.46.00;	author petere;	state Exp;
branches;
next	1.22;

1.22
date	2001.09.16.22.53.52;	author petere;	state Exp;
branches;
next	1.21;

1.21
date	2001.09.15.16.08.59;	author petere;	state Exp;
branches;
next	1.20;

1.20
date	2001.09.13.15.55.23;	author petere;	state Exp;
branches;
next	1.19;

1.19
date	2001.09.10.21.58.47;	author petere;	state Exp;
branches;
next	1.18;

1.18
date	2001.09.10.04.15.41;	author momjian;	state Exp;
branches;
next	1.17;

1.17
date	2001.09.10.03.02.06;	author ishii;	state Exp;
branches;
next	1.16;

1.16
date	2001.02.09.19.24.09;	author momjian;	state Exp;
branches;
next	1.15;

1.15
date	2001.01.20.00.05.54;	author momjian;	state Exp;
branches;
next	1.14;

1.14
date	2000.12.21.22.55.27;	author petere;	state Exp;
branches;
next	1.13;

1.13
date	2000.09.29.20.21.34;	author petere;	state Exp;
branches;
next	1.12;

1.12
date	2000.05.15.12.42.23;	author momjian;	state Exp;
branches;
next	1.11;

1.11
date	2000.05.02.20.01.52;	author thomas;	state Exp;
branches;
next	1.10;

1.10
date	2000.03.31.03.27.41;	author thomas;	state Exp;
branches;
next	1.9;

1.9
date	2000.03.15.17.07.41;	author momjian;	state Exp;
branches;
next	1.8;

1.8
date	99.11.11.21.52.28;	author momjian;	state Exp;
branches;
next	1.7;

1.7
date	99.10.04.15.18.54;	author thomas;	state Exp;
branches;
next	1.6;

1.6
date	99.06.14.07.36.12;	author thomas;	state Exp;
branches;
next	1.5;

1.5
date	99.03.17.21.58.25;	author momjian;	state Exp;
branches;
next	1.4;

1.4
date	98.12.29.02.24.17;	author thomas;	state Exp;
branches;
next	1.3;

1.3
date	98.10.17.22.01.14;	author tgl;	state Exp;
branches;
next	1.2;

1.2
date	98.07.29.06.49.59;	author thomas;	state Exp;
branches;
next	1.1;

1.1
date	98.03.01.08.15.58;	author thomas;	state Exp;
branches;
next	;

1.29.2.1
date	2003.09.07.04.36.42;	author momjian;	state Exp;
branches;
next	;

1.31.2.1
date	2003.11.12.20.05.14;	author petere;	state Exp;
branches;
next	;

1.37.2.1
date	2006.03.02.21.49.19;	author tgl;	state Exp;
branches;
next	;

1.49.2.1
date	2010.08.09.12.00.53;	author rhaas;	state Exp;
branches;
next	1.49.2.2;

1.49.2.2
date	2010.08.10.02.57.19;	author rhaas;	state Exp;
branches;
next	;

1.53.2.1
date	2010.08.09.12.00.39;	author rhaas;	state Exp;
branches;
next	1.53.2.2;

1.53.2.2
date	2010.08.10.02.57.03;	author rhaas;	state Exp;
branches;
next	;


desc
@@


1.55
log
@Use double quotes rather than double quotes for libpq target anchors.

Per observation from Tom Lane that the previous patch to these files was
not consistent with what is done elsewhere in the docs.
@
text
@<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.54 2010/08/09 12:00:24 rhaas Exp $ -->

 <chapter id="largeObjects">
  <title>Large Objects</title>

  <indexterm zone="largeobjects"><primary>large object</></>
  <indexterm><primary>BLOB</><see>large object</></>

   <para>
    <productname>PostgreSQL</productname> has a <firstterm>large object</>
    facility, which provides stream-style access to user data that is stored
    in a special large-object structure.  Streaming access is useful
    when working with data values that are too large to manipulate
    conveniently as a whole.
   </para>

   <para>
    This chapter describes the implementation and the programming and
    query language interfaces to <productname>PostgreSQL</productname>
    large object data.  We use the <application>libpq</application> C
    library for the examples in this chapter, but most programming
    interfaces native to <productname>PostgreSQL</productname> support
    equivalent functionality.  Other interfaces might use the large
    object interface internally to provide generic support for large
    values.  This is not described here.
   </para>

  <sect1 id="lo-intro">
   <title>Introduction</title>

   <indexterm>
    <primary>TOAST</primary>
    <secondary>versus large objects</secondary>
   </indexterm>

   <para>
    All large objects are placed in a single system table called
    <classname>pg_largeobject</classname>.
    <productname>PostgreSQL</productname> also supports a storage system called
    <quote><acronym>TOAST</acronym></quote> that automatically stores values
    larger than a single database page into a secondary storage area per table.
    This makes the large object facility partially obsolete.  One
    remaining advantage of the large object facility is that it allows values
    up to 2 GB in size, whereas <acronym>TOAST</acronym>ed fields can be at
    most 1 GB.  Also, large objects can be randomly modified using a read/write 
    API that is more efficient than performing such operations using
    <acronym>TOAST</acronym>.
   </para>

  </sect1>

  <sect1 id="lo-implementation">
   <title>Implementation Features</title>

   <para>
    The large object implementation breaks large
    objects up into <quote>chunks</quote> and stores the chunks in
    rows in the database.  A B-tree index guarantees fast
    searches for the correct chunk number when doing random
    access reads and writes.
   </para>

   <para>
    As of <productname>PostgreSQL</> 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">.  
    For compatibility with prior releases, see
    <xref linkend="guc-lo-compat-privileges">.
    <literal>SELECT</literal> privileges are required to read a large
    object, and 
    <literal>UPDATE</literal> privileges are required to write to or
    truncate it.
    Only the large object owner (or the database superuser) can unlink, comment
    on, or change the owner of a large object.
   </para>
  </sect1>

  <sect1 id="lo-interfaces">
   <title>Client Interfaces</title>

   <para>
    This section describes the facilities that
    <productname>PostgreSQL</productname> client interface libraries
    provide for accessing large objects.  All large object
    manipulation using these functions <emphasis>must</emphasis> take
    place within an SQL transaction block.
    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>
    Client applications which use the large object interface in
    <application>libpq</application> should include the header file
    <filename>libpq/libpq-fs.h</filename> and link with the
    <application>libpq</application> library.
   </para>

   <sect2 id="lo-create">
    <title>Creating a Large Object</title>

    <para>
     The function
<synopsis>
Oid lo_creat(PGconn *conn, int mode);
</synopsis>
     <indexterm><primary>lo_creat</></>
     creates a new large object.  
     The return value is the OID that was assigned to the new large object,
     or <symbol>InvalidOid</symbol> (zero) on failure.

     <replaceable class="parameter">mode</replaceable> is unused and
     ignored as of <productname>PostgreSQL</productname> 8.1; however, for
     backwards compatibility with earlier releases it is best to
     set it to <symbol>INV_READ</symbol>, <symbol>INV_WRITE</symbol>,
     or <symbol>INV_READ</symbol> <literal>|</> <symbol>INV_WRITE</symbol>.
     (These symbolic constants are defined
     in the header file <filename>libpq/libpq-fs.h</filename>.)
    </para>

    <para>
     An example:
<programlisting>
inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
</programlisting>
    </para>

    <para>
     The function
<synopsis>
Oid lo_create(PGconn *conn, Oid lobjId);
</synopsis>
     <indexterm><primary>lo_create</></>
     also 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</> assigns an unused
     OID (this is the same behavior as <function>lo_creat</>).
     The return value is the OID that was assigned to the new large object,
     or <symbol>InvalidOid</symbol> (zero) on failure.
    </para>

    <para>
     <function>lo_create</> is new as of <productname>PostgreSQL</productname>
     8.1; if this function is run against an older server version, it will
     fail and return <symbol>InvalidOid</symbol>.
    </para>

    <para>
     An example:
<programlisting>
inv_oid = lo_create(conn, desired_oid);
</programlisting>
    </para>
   </sect2>

   <sect2 id="lo-import">
    <title>Importing a Large Object</title>

    <para>
     To import an operating system file as a large object, call
<synopsis>
Oid lo_import(PGconn *conn, const char *filename);
</synopsis>
     <indexterm><primary>lo_import</></>
     <replaceable class="parameter">filename</replaceable> 
     specifies the operating system name of
     the file to be imported as a large object.
     The return value is the OID that was assigned to the new large object,
     or <symbol>InvalidOid</symbol> (zero) on failure.
     Note that the file is read by the client interface library, not by
     the server; so it must exist in the client file system and be readable
     by the client application.
    </para>

    <para>
     The function
<synopsis>
Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
</synopsis>
     <indexterm><primary>lo_import_with_oid</></>
     also imports 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_import_with_oid</> assigns an unused
     OID (this is the same behavior as <function>lo_import</>).
     The return value is the OID that was assigned to the new large object,
     or <symbol>InvalidOid</symbol> (zero) on failure.
    </para>

    <para>
     <function>lo_import_with_oid</> is new as of <productname>PostgreSQL</productname>
     8.4 and uses <function>lo_create</function> internally which is new in 8.1; if this function is run against 8.0 or before, it will
     fail and return <symbol>InvalidOid</symbol>.
    </para>
   </sect2>

   <sect2 id="lo-export">
    <title>Exporting a Large Object</title>

    <para>
     To export a large object
     into an operating system file, call
<synopsis>
int lo_export(PGconn *conn, Oid lobjId, const char *filename);
</synopsis>
     <indexterm><primary>lo_export</></>
     The <parameter>lobjId</parameter> argument specifies the OID of the large
     object to export and the <parameter>filename</parameter> argument
     specifies the operating system name of the file.  Note that the file is
     written by the client interface library, not by the server.  Returns 1
     on success, -1 on failure.
    </para>
   </sect2>

   <sect2 id="lo-open">
    <title>Opening an Existing Large Object</title>

    <para>
     To open an existing large object for reading or writing, call
<synopsis>
int lo_open(PGconn *conn, Oid lobjId, int mode);
</synopsis>
     <indexterm><primary>lo_open</></>
     The <parameter>lobjId</parameter> argument specifies the OID of the large
     object to open.   The <parameter>mode</parameter> bits control whether the
     object is opened for reading (<symbol>INV_READ</>), writing
     (<symbol>INV_WRITE</symbol>), or both.
     (These symbolic constants are defined
     in the header file <filename>libpq/libpq-fs.h</filename>.)
     A large object cannot be opened before it is created.
     <function>lo_open</function> returns a (non-negative) large object
     descriptor for later use in <function>lo_read</function>,
     <function>lo_write</function>, <function>lo_lseek</function>,
     <function>lo_tell</function>, and <function>lo_close</function>.
     The descriptor is only valid for 
     the duration of the current transaction.
     On failure, -1 is returned.
    </para>

    <para>
     The server currently does not distinguish between modes
     <symbol>INV_WRITE</symbol> and <symbol>INV_READ</> <literal>|</>
     <symbol>INV_WRITE</symbol>: you are allowed to read from the descriptor
     in either case.  However there is a significant difference between
     these modes and <symbol>INV_READ</> alone: with <symbol>INV_READ</>
     you cannot write on the descriptor, and the data read from it will
     reflect the contents of the large object at the time of the transaction
     snapshot that was active when <function>lo_open</> was executed,
     regardless of later writes by this or other transactions.  Reading
     from a descriptor opened with <symbol>INV_WRITE</symbol> returns
     data that reflects all writes of other committed transactions as well
     as writes of the current transaction.  This is similar to the behavior
     of <literal>SERIALIZABLE</> versus <literal>READ COMMITTED</> transaction
     modes for ordinary SQL <command>SELECT</> commands.
    </para>

    <para>
     An example:
<programlisting>
inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
</programlisting>
    </para>
</sect2>

<sect2 id="lo-write">
<title>Writing Data to a Large Object</title>

<para>
     The function
<synopsis>
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
</synopsis>
     <indexterm><primary>lo_write</></> writes
     <parameter>len</parameter> bytes from <parameter>buf</parameter>
     to large object descriptor <parameter>fd</>.  The <parameter>fd</parameter>
     argument must have been returned by a previous
     <function>lo_open</function>.  The number of bytes actually
     written is returned.  In the event of an error, the return value
     is negative.
</para>
</sect2>

<sect2 id="lo-read">
<title>Reading Data from a Large Object</title>

<para>
     The function
<synopsis>
int lo_read(PGconn *conn, int fd, char *buf, size_t len);
</synopsis>
     <indexterm><primary>lo_read</></> reads
     <parameter>len</parameter> bytes from large object descriptor
     <parameter>fd</parameter> into <parameter>buf</parameter>. The
     <parameter>fd</parameter> argument must have been returned by a
     previous <function>lo_open</function>.  The number of bytes
     actually read is returned. In the event of an error, the return
     value is negative.
</para>
</sect2>

<sect2 id="lo-seek">
<title>Seeking in a Large Object</title>

<para>
     To change the current read or write location associated with a
     large object descriptor, call
<synopsis>
int lo_lseek(PGconn *conn, int fd, int offset, int whence);
</synopsis>
     <indexterm><primary>lo_lseek</></> This function moves the
     current location pointer for the large object descriptor identified by
     <parameter>fd</> to the new location specified by
     <parameter>offset</>.  The valid values for <parameter>whence</>
     are <symbol>SEEK_SET</> (seek from object start),
     <symbol>SEEK_CUR</> (seek from current position), and
     <symbol>SEEK_END</> (seek from object end).  The return value is
     the new location pointer, or -1 on error.
</para>
</sect2>

<sect2 id="lo-tell">
<title>Obtaining the Seek Position of a Large Object</title>

<para>
     To obtain the current read or write location of a large object descriptor,
     call
<synopsis>
int lo_tell(PGconn *conn, int fd);
</synopsis>
     <indexterm><primary>lo_tell</></> If there is an error, the
     return value is negative.
</para>
</sect2>

<sect2 id="lo-truncate">
<title>Truncating a Large Object</title>

<para>
     To truncate a large object to a given length, call
<synopsis>
int lo_truncate(PGcon *conn, int fd, size_t len);
</synopsis>
     <indexterm><primary>lo_truncate</></> truncates the large object
     descriptor <parameter>fd</> to length <parameter>len</>.  The
     <parameter>fd</parameter> argument must have been returned by a
     previous <function>lo_open</function>.  If <parameter>len</> is
     greater than the current large object length, the large object
     is extended with null bytes ('\0').
</para>

<para>
     The file offset is not changed.
</para>

<para>
     On success <function>lo_truncate</function> returns
     zero.  On error, the return value is negative.
</para>

<para>
     <function>lo_truncate</> is new as of <productname>PostgreSQL</productname>
     8.3; if this function is run against an older server version, it will
     fail and return a negative value.
</para>
</sect2>

<sect2 id="lo-close">
<title>Closing a Large Object Descriptor</title>

<para>
     A large object descriptor can be closed by calling
<synopsis>
int lo_close(PGconn *conn, int fd);
</synopsis>
     <indexterm><primary>lo_close</></> where <parameter>fd</> is a
     large object descriptor returned by <function>lo_open</function>.
     On success, <function>lo_close</function> returns zero.  On
     error, the return value is negative.
</para>

<para>
     Any large  object  descriptors that remain open at the end of a
     transaction will be closed automatically.
</para>
</sect2>

   <sect2 id="lo-unlink">
    <title>Removing a Large Object</title>

    <para>
     To remove a large object from the database, call
<synopsis>
int lo_unlink(PGconn *conn, Oid lobjId);
</synopsis>
     <indexterm><primary>lo_unlink</></> The
     <parameter>lobjId</parameter> argument specifies the OID of the
     large object to remove.  Returns 1 if successful, -1 on failure.
    </para>
   </sect2>

</sect1>

<sect1 id="lo-funcs">
<title>Server-Side Functions</title>

  <para>
   There are server-side functions callable from SQL that correspond to
   each of the client-side functions described above; indeed, for the
   most part the client-side functions are simply interfaces to the
   equivalent server-side functions.  The ones that are actually useful
   to call via SQL commands are
   <function>lo_creat</function><indexterm><primary>lo_creat</></>,
   <function>lo_create</function><indexterm><primary>lo_create</></>,
   <function>lo_unlink</function><indexterm><primary>lo_unlink</></>,
   <function>lo_import</function><indexterm><primary>lo_import</></>, and
   <function>lo_export</function><indexterm><primary>lo_export</></>.
   Here are examples of their use:

<programlisting>
CREATE TABLE image (
    name            text,
    raster          oid
);

SELECT lo_creat(-1);       -- returns OID of new, empty large object

SELECT lo_create(43213);   -- attempts to create large object with OID 43213

SELECT lo_unlink(173454);  -- deletes large object with OID 173454

INSERT INTO image (name, raster)
    VALUES ('beautiful image', lo_import('/etc/motd'));

INSERT INTO image (name, raster)  -- same as above, but specify OID to use
    VALUES ('beautiful image', lo_import('/etc/motd', 68583));

SELECT lo_export(image.raster, '/tmp/motd') FROM image
    WHERE name = 'beautiful image';
</programlisting>
  </para>

  <para>
    The server-side <function>lo_import</function> and
    <function>lo_export</function> functions behave considerably differently
    from their client-side analogs.  These two functions read and write files
    in the server's file system, using the permissions of the database's
    owning user.  Therefore, their use is restricted to superusers.  In
    contrast, the client-side import and export functions read and write files
    in the client's file system, using the permissions of the client program.
    The client-side functions do not require superuser privilege.
  </para>

</sect1>

<sect1 id="lo-examplesect">
<title>Example Program</title>

<para>
     <xref linkend="lo-example"> is a sample program which shows how the large object  
     interface
     in <application>libpq</> can be used.  Parts of the program are 
     commented out but are left in the source for  the  reader's
     benefit.  This program can also be found in
     <filename>src/test/examples/testlo.c</filename> in the source distribution.
</para>

  <example id="lo-example">
   <title>Large Objects with <application>libpq</application> Example Program</title>
<programlisting><![CDATA[
/*--------------------------------------------------------------
 *
 * testlo.c--
 *    test using large objects with libpq
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *--------------------------------------------------------------
 */
#include <stdio.h>
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"

#define BUFSIZE          1024

/*
 * importFile
 *    import file "in_filename" into database as large object "lobjOid"
 *
 */
Oid
importFile(PGconn *conn, char *filename)
{
    Oid         lobjId;
    int         lobj_fd;
    char        buf[BUFSIZE];
    int         nbytes,
                tmp;
    int         fd;

    /*
     * open the file to be read in
     */
    fd = open(filename, O_RDONLY, 0666);
    if (fd < 0)
    {                           /* error */
        fprintf(stderr, "cannot open unix file %s\n", filename);
    }

    /*
     * create the large object
     */
    lobjId = lo_creat(conn, INV_READ | INV_WRITE);
    if (lobjId == 0)
        fprintf(stderr, "cannot create large object\n");

    lobj_fd = lo_open(conn, lobjId, INV_WRITE);

    /*
     * read in from the Unix file and write to the inversion file
     */
    while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
    {
        tmp = lo_write(conn, lobj_fd, buf, nbytes);
        if (tmp < nbytes)
            fprintf(stderr, "error while reading large object\n");
    }

    (void) close(fd);
    (void) lo_close(conn, lobj_fd);

    return lobjId;
}

void
pickout(PGconn *conn, Oid lobjId, int start, int len)
{
    int         lobj_fd;
    char       *buf;
    int         nbytes;
    int         nread;

    lobj_fd = lo_open(conn, lobjId, INV_READ);
    if (lobj_fd < 0)
    {
        fprintf(stderr, "cannot open large object %d\n",
                lobjId);
    }

    lo_lseek(conn, lobj_fd, start, SEEK_SET);
    buf = malloc(len + 1);

    nread = 0;
    while (len - nread > 0)
    {
        nbytes = lo_read(conn, lobj_fd, buf, len - nread);
        buf[nbytes] = ' ';
        fprintf(stderr, ">>> %s", buf);
        nread += nbytes;
    }
    free(buf);
    fprintf(stderr, "\n");
    lo_close(conn, lobj_fd);
}

void
overwrite(PGconn *conn, Oid lobjId, int start, int len)
{
    int         lobj_fd;
    char       *buf;
    int         nbytes;
    int         nwritten;
    int         i;

    lobj_fd = lo_open(conn, lobjId, INV_WRITE);
    if (lobj_fd < 0)
    {
        fprintf(stderr, "cannot open large object %d\n",
                lobjId);
    }

    lo_lseek(conn, lobj_fd, start, SEEK_SET);
    buf = malloc(len + 1);

    for (i = 0; i < len; i++)
        buf[i] = 'X';
    buf[i] = ' ';

    nwritten = 0;
    while (len - nwritten > 0)
    {
        nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
        nwritten += nbytes;
    }
    free(buf);
    fprintf(stderr, "\n");
    lo_close(conn, lobj_fd);
}

/*
 * exportFile
 *    export large object "lobjOid" to file "out_filename"
 *
 */
void
exportFile(PGconn *conn, Oid lobjId, char *filename)
{
    int         lobj_fd;
    char        buf[BUFSIZE];
    int         nbytes,
                tmp;
    int         fd;

    /*
     * open the large object
     */
    lobj_fd = lo_open(conn, lobjId, INV_READ);
    if (lobj_fd < 0)
    {
        fprintf(stderr, "cannot open large object %d\n",
                lobjId);
    }

    /*
     * open the file to be written to
     */
    fd = open(filename, O_CREAT | O_WRONLY, 0666);
    if (fd < 0)
    {                           /* error */
        fprintf(stderr, "cannot open unix file %s\n",
                filename);
    }

    /*
     * read in from the inversion file and write to the Unix file
     */
    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
    {
        tmp = write(fd, buf, nbytes);
        if (tmp < nbytes)
        {
            fprintf(stderr, "error while writing %s\n",
                    filename);
        }
    }

    (void) lo_close(conn, lobj_fd);
    (void) close(fd);

    return;
}

void
exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}

int
main(int argc, char **argv)
{
    char       *in_filename,
               *out_filename;
    char       *database;
    Oid         lobjOid;
    PGconn     *conn;
    PGresult   *res;

    if (argc != 4)
    {
        fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
                argv[0]);
        exit(1);
    }

    database = argv[1];
    in_filename = argv[2];
    out_filename = argv[3];

    /*
     * set up the connection
     */
    conn = PQsetdb(NULL, NULL, NULL, NULL, database);

    /* check to see that the backend connection was successfully made */
    if (PQstatus(conn) == CONNECTION_BAD)
    {
        fprintf(stderr, "Connection to database '%s' failed.\n", database);
        fprintf(stderr, "%s", PQerrorMessage(conn));
        exit_nicely(conn);
    }

    res = PQexec(conn, "begin");
    PQclear(res);

    printf("importing file %s\n", in_filename);
/*  lobjOid = importFile(conn, in_filename); */
    lobjOid = lo_import(conn, in_filename);
/*
    printf("as large object %d.\n", lobjOid);

    printf("picking out bytes 1000-2000 of the large object\n");
    pickout(conn, lobjOid, 1000, 1000);

    printf("overwriting bytes 1000-2000 of the large object with X's\n");
    overwrite(conn, lobjOid, 1000, 1000);
*/

    printf("exporting large object to file %s\n", out_filename);
/*    exportFile(conn, lobjOid, out_filename); */
    lo_export(conn, lobjOid, out_filename);

    res = PQexec(conn, "end");
    PQclear(res);
    PQfinish(conn);
    exit(0);
}
]]>
</programlisting>
</example>

</sect1>
</chapter>
@


1.54
log
@Provide stable target anchors for libpq functions.

Daniele Varrazzo
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.53 2010/04/03 07:22:55 petere Exp $ -->
d102 1
a102 1
   <sect2 id='lo-create'>
@


1.53
log
@Remove unnecessary xref endterm attributes and title ids

The endterm attribute is mainly useful when the toolchain does not support
automatic link target text generation for a particular situation.  In  the
past, this was required by the man page tools for all reference page links,
but that is no longer the case, and it now actually gets in the way of
proper automatic link text generation.  The only remaining use cases are
currently xrefs to refsects.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.52 2010/02/17 04:19:37 tgl Exp $ -->
d102 1
a102 1
   <sect2>
d161 1
a161 1
   <sect2>
d203 1
a203 1
   <sect2>
d221 1
a221 1
   <sect2>
d271 1
a271 1
<sect2>
d289 1
a289 1
<sect2>
d307 1
a307 1
<sect2>
d327 1
a327 1
<sect2>
d341 1
a341 1
<sect2>
d373 1
a373 1
<sect2>
d393 1
a393 1
   <sect2>
@


1.53.2.1
log
@Provide stable target anchors for libpq functions.

Daniele Varrazzo
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.53 2010/04/03 07:22:55 petere Exp $ -->
d102 1
a102 1
   <sect2 id='lo-create'>
d161 1
a161 1
   <sect2 id="lo-import">
d203 1
a203 1
   <sect2 id="lo-export">
d221 1
a221 1
   <sect2 id="lo-open">
d271 1
a271 1
<sect2 id="lo-write">
d289 1
a289 1
<sect2 id="lo-read">
d307 1
a307 1
<sect2 id="lo-seek">
d327 1
a327 1
<sect2 id="lo-tell">
d341 1
a341 1
<sect2 id="lo-truncate">
d373 1
a373 1
<sect2 id="lo-close">
d393 1
a393 1
   <sect2 id="lo-unlink">
@


1.53.2.2
log
@Use double quotes rather than double quotes for libpq target anchors.

Per observation from Tom Lane that the previous patch to these files was
not consistent with what is done elsewhere in the docs.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.53.2.1 2010/08/09 12:00:39 rhaas Exp $ -->
d102 1
a102 1
   <sect2 id="lo-create">
@


1.52
log
@Stamp HEAD as 9.0devel, and update various places that were referring to 8.5
(hope I got 'em all).  Per discussion, this release will be 9.0 not 8.5.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.51 2009/12/17 14:36:16 rhaas Exp $ -->
d4 1
a4 1
  <title id="largeObjects-title">Large Objects</title>
d66 2
a67 2
    <xref linkend="sql-grant" endterm="sql-grant-title"> and
    <xref linkend="sql-revoke" endterm="sql-revoke-title">.  
@


1.51
log
@Improve documentation for pg_largeobject changes.

Rewrite the documentation in more idiomatic English, and in the process make
it somewhat more succinct.  Move the discussion of specific large object
privileges out of the "server-side functions" section, where it certainly
doesn't belong, and into "implementation features".  That might not be
exactly right either, but it doesn't seem worth creating a new section for
this amount of information. Fix a few spelling and layout problems, too.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.50 2009/12/11 03:34:55 itagaki Exp $ -->
d64 1
a64 1
    As of <productname>PostgreSQL</> 8.5, large objects have an owner
@


1.50
log
@Add large object access control.

A new system catalog pg_largeobject_metadata manages
ownership and access privileges of large objects.

KaiGai Kohei, reviewed by Jaime Casanova.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.49 2008/12/07 23:46:39 alvherre Exp $ -->
d62 15
d456 1
a456 2
    The client-side functions can be used by any
    <productname>PostgreSQL</productname> user.
a458 50
  <sect2 id="lo-func-privilege">
   <title>Large object and privileges</title>
   <para>
    Note that access control feature was not supported in the 8.4.x series
    and earlier release.
    Also see the <xref linkend="guc-lo-compat-privileges"> compatibility
    option.
   </para>
   <para>
    Now it supports access controls on large objects, and allows the owner
    of large objects to set up access rights using
    <xref linkend="sql-grant" endterm="sql-grant-title"> and
    <xref linkend="sql-revoke" endterm="sql-revoke-title"> statement.
   </para>
   <para>
    Two permissions are defined on the large object class.
    These are checked only when <xref linkend="guc-lo-compat-privileges">
    option is disabled.
   </para>
   <para>
    The first is <literal>SELECT</literal>.
    It is required on <function>loread()</function> function.
    Note that when we open large object with read-only mode, we can see
    a static image even if other concurrent transaction modified the
    same large object.
    This principle is also applied on the access rights of large objects.
    Even if a transaction modified access rights and commit it, it is
    not invisible from other transaction which already opened the large
    object.
   </para>
   <para>
    The second is <literal>UPDATE</literal>.
    It is required on <function>lowrite()</function> function and
    <function>lo_truncate()</function> function.
   </para>
   <para>
    In addition, <function>lo_unlink()</function> function,
    <command>COMMENT ON</command> and <command>ALTER LARGE OBJECT</command>
    statements needs ownership of the large object to be accessed.
   </para>
   <para>
    You may wonder why <literal>SELECT</literal> is not checked on the
    <function>lo_export()</function> function or <literal>UPDATE</literal>
    is not checked on the <function>lo_import</function> function.

    These functions originally require database superuser privilege,
    and it allows to bypass the default database privilege checks,
    so we don't need to check an obvious test twice.
   </para>
  </sect2>
@


1.49
log
@Desultorily enclose programlisting tags in CDATA, to get rid of some obnoxious
SGML-escaping.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.48 2008/03/22 01:55:14 ishii Exp $ -->
d444 51
@


1.49.2.1
log
@Provide stable target anchors for libpq functions.

Daniele Varrazzo
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.49 2008/12/07 23:46:39 alvherre Exp $ -->
d87 1
a87 1
   <sect2 id='lo-create'>
d146 1
a146 1
   <sect2 id="lo-import">
d188 1
a188 1
   <sect2 id="lo-export">
d206 1
a206 1
   <sect2 id="lo-open">
d256 1
a256 1
<sect2 id="lo-write">
d274 1
a274 1
<sect2 id="lo-read">
d292 1
a292 1
<sect2 id="lo-seek">
d312 1
a312 1
<sect2 id="lo-tell">
d326 1
a326 1
<sect2 id="lo-truncate">
d358 1
a358 1
<sect2 id="lo-close">
d378 1
a378 1
   <sect2 id="lo-unlink">
@


1.49.2.2
log
@Use double quotes rather than double quotes for libpq target anchors.

Per observation from Tom Lane that the previous patch to these files was
not consistent with what is done elsewhere in the docs.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.49.2.1 2010/08/09 12:00:53 rhaas Exp $ -->
d87 1
a87 1
   <sect2 id="lo-create">
@


1.48
log
@Add server side lo_import(filename, oid) function.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.47 2008/03/19 00:39:33 ishii Exp $ -->
d460 1
a460 1
<programlisting>
d470 3
a472 3
#include &lt;stdio.h&gt;
#include &quot;libpq-fe.h&quot;
#include &quot;libpq/libpq-fs.h&quot;
d478 1
a478 1
 *    import file &quot;in_filename&quot; into database as large object &quot;lobjOid&quot;
d495 1
a495 1
    if (fd &lt; 0)
d497 1
a497 1
        fprintf(stderr, &quot;cannot open unix file %s\n&quot;, filename);
d505 1
a505 1
        fprintf(stderr, &quot;cannot create large object\n&quot;);
d512 1
a512 1
    while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0)
d515 2
a516 2
        if (tmp &lt; nbytes)
            fprintf(stderr, &quot;error while reading large object\n&quot;);
d534 1
a534 1
    if (lobj_fd &lt; 0)
d536 1
a536 1
        fprintf(stderr, &quot;cannot open large object %d\n&quot;,
d544 1
a544 1
    while (len - nread &gt; 0)
d548 1
a548 1
        fprintf(stderr, &quot;&gt;&gt;&gt; %s&quot;, buf);
d552 1
a552 1
    fprintf(stderr, &quot;\n&quot;);
d566 1
a566 1
    if (lobj_fd &lt; 0)
d568 1
a568 1
        fprintf(stderr, &quot;cannot open large object %d\n&quot;,
d575 1
a575 1
    for (i = 0; i &lt; len; i++)
d580 1
a580 1
    while (len - nwritten &gt; 0)
d586 1
a586 1
    fprintf(stderr, &quot;\n&quot;);
d592 1
a592 1
 *    export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
d608 1
a608 1
    if (lobj_fd &lt; 0)
d610 1
a610 1
        fprintf(stderr, &quot;cannot open large object %d\n&quot;,
d618 1
a618 1
    if (fd &lt; 0)
d620 1
a620 1
        fprintf(stderr, &quot;cannot open unix file %s\n&quot;,
d627 1
a627 1
    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0)
d630 1
a630 1
        if (tmp &lt; nbytes)
d632 1
a632 1
            fprintf(stderr, &quot;error while writing %s\n&quot;,
d662 1
a662 1
        fprintf(stderr, &quot;Usage: %s database_name in_filename out_filename\n&quot;,
d679 2
a680 2
        fprintf(stderr, &quot;Connection to database '%s' failed.\n&quot;, database);
        fprintf(stderr, &quot;%s&quot;, PQerrorMessage(conn));
d684 1
a684 1
    res = PQexec(conn, &quot;begin&quot;);
d687 1
a687 1
    printf(&quot;importing file %s\n&quot;, in_filename);
d691 1
a691 1
    printf(&quot;as large object %d.\n&quot;, lobjOid);
d693 1
a693 1
    printf(&quot;picking out bytes 1000-2000 of the large object\n&quot;);
d696 1
a696 1
    printf(&quot;overwriting bytes 1000-2000 of the large object with X's\n&quot;);
d700 1
a700 1
    printf(&quot;exporting large object to file %s\n&quot;, out_filename);
d704 1
a704 1
    res = PQexec(conn, &quot;end&quot;);
d709 1
@


1.47
log
@Add libpq new API lo_import_with_oid() which is similar to lo_import()
except that lob's oid can be specified.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.46 2007/03/14 00:15:26 tgl Exp $ -->
d425 3
@


1.46
log
@Fix broken markup, strange tab width.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.45 2007/03/03 19:52:45 momjian Exp $ -->
d164 22
@


1.45
log
@Add lo_truncate() to backend and libpq for large object truncation.

Kris Jurka
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.44 2007/02/01 19:10:24 momjian Exp $ -->
d334 1
@


1.44
log
@Wording cleanup for error messages.  Also change can't -> cannot.

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.43 2007/01/31 20:56:17 momjian Exp $ -->
d305 31
@


1.43
log
@Update documentation on may/can/might:

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".

Also update two error messages mentioned in the documenation to match.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.42 2006/10/23 18:10:31 petere Exp $ -->
d440 1
a440 1
        fprintf(stderr, &quot;can't open unix file %s\n&quot;, filename);
d448 1
a448 1
        fprintf(stderr, &quot;can't create large object\n&quot;);
d479 1
a479 1
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
d511 1
a511 1
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
d553 1
a553 1
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
d563 1
a563 1
        fprintf(stderr, &quot;can't open unix file %s\n&quot;,
@


1.42
log
@Spellchecking and such
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.41 2006/09/16 00:30:14 momjian Exp $ -->
d23 1
a23 1
    equivalent functionality.  Other interfaces may use the large
d308 1
a308 1
     A large object descriptor may be closed by calling
d395 1
a395 1
     in  <application>libpq</>  can  be used.  Parts of the program are 
@


1.41
log
@Remove emacs info from footer of SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.40 2006/04/23 03:39:52 momjian Exp $ -->
d98 1
a98 1
     or InvalidOid (zero) on failure.
d126 1
a126 1
     is InvalidOid (zero) then <function>lo_create</> assigns an unused
d129 1
a129 1
     or InvalidOid (zero) on failure.
d135 1
a135 1
     fail and return InvalidOid.
d159 1
a159 1
     or InvalidOid (zero) on failure.
d161 1
a161 1
     the server; so it must exist in the client filesystem and be readable
@


1.40
log
@Removes or minimizes some documentation mentions of backward
compatibility for release 7.2 and earlier.  I have not altered any
mentions of release 7.3 or later.  The release notes were not modified,
so the changes are still documented, just not in the main docs.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.39 2006/03/10 19:10:48 momjian Exp $ -->
a656 17

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
@


1.39
log
@Make $PostgreSQL CVS tags consistent for SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.49 2005/04/09 03:52:43 momjian Exp $ -->
d28 7
a34 2
  <sect1 id="lo-history">
   <title>History</title>
d37 1
a37 16
    <productname>POSTGRES 4.2</productname>, the indirect predecessor
    of <productname>PostgreSQL</productname>, supported three standard
    implementations of large objects: as files external to the
    <productname>POSTGRES</productname> server, as external files
    managed by the <productname>POSTGRES</productname> server, and as
    data stored within the <productname>POSTGRES</productname>
    database. This caused considerable confusion among users. As a
    result, only support for large objects as data stored within the
    database is retained in <productname>PostgreSQL</productname>.
    Even though this is slower to access, it provides stricter data
    integrity.  For historical reasons, this storage scheme is
    referred to as <firstterm>Inversion large
    objects</firstterm>. (You will see the term Inversion used
    occasionally to mean the same thing as large object.)  Since
    <productname>PostgreSQL 7.1</productname>, all large objects are
    placed in one system table called
d39 4
a42 11
   </para>

   <para>
    <indexterm>
     <primary>TOAST</primary>
     <secondary>versus large objects</secondary>
    </indexterm>
    <productname>PostgreSQL</productname> 7.1 introduced a mechanism
    (nicknamed <quote><acronym>TOAST</acronym></quote>) that allows
    data values to be much larger than single pages.  This
    makes the large object facility partially obsolete.  One
d45 3
a47 3
    most 1 GB.  Also, large objects can be manipulated piece-by-piece much more
    easily than ordinary data fields, so the practical limits are considerably
    different.
d56 2
a57 2
    The large object implementation breaks  large
    objects  up  into  <quote>chunks</quote>  and  stores  the chunks in
d72 1
a72 4
    place within an SQL transaction block.  (This requirement is
    strictly enforced as of <productname>PostgreSQL 6.5</>, though it
    has been an implicit requirement in previous versions, resulting
    in misbehavior if ignored.)
@


1.38
log
@Fix ancient error in large objects usage example: overwrite() subroutine
was opening with INV_READ flag and then writing.  Prior to 8.1 the backend
did not reject this, but now it does.
@
text
@d1 1
a1 3
<!--
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.37 2005/06/13 02:26:46 tgl Exp $
-->
@


1.37
log
@Adjust lo_open() so that specifying INV_READ without INV_WRITE creates
a descriptor that uses the current transaction snapshot, rather than
SnapshotNow as it did before (and still does if INV_WRITE is set).
This means pg_dump will now dump a consistent snapshot of large object
contents, as it never could do before.  Also, add a lo_create() function
that is similar to lo_creat() but allows the desired OID of the large
object to be specified.  This will simplify pg_restore considerably
(but I'll fix that in a separate commit).
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.36 2005/01/10 00:04:38 tgl Exp $
d530 1
a530 1
    lobj_fd = lo_open(conn, lobjId, INV_READ);
d556 2
a557 1
 * exportFile *    export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
d570 1
a570 1
     * create an inversion &quot;object&quot;
d590 1
a590 1
     * read in from the Unix file and write to the inversion file
@


1.37.2.1
log
@Fix ancient error in large objects usage example: overwrite() subroutine
was opening with INV_READ flag and then writing.  Prior to 8.1 the backend
did not reject this, but now it does.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.37 2005/06/13 02:26:46 tgl Exp $
d530 1
a530 1
    lobj_fd = lo_open(conn, lobjId, INV_WRITE);
d556 1
a556 2
 * exportFile
 *    export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
d569 1
a569 1
     * open the large object
d589 1
a589 1
     * read in from the inversion file and write to the Unix file
@


1.36
log
@Add some real documentation about TOAST (finally).  Combine this with
the old 'page' chapter and the recently added 'filelayout' chapter to
make a coherent chapter about PostgreSQL's physical storage layout.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.35 2005/01/08 22:13:33 tgl Exp $
d118 1
a118 12
     creates a new large  object.  
     <replaceable class="parameter">mode</replaceable>  is  a  bit mask
     describing  several  different  attributes  of  the new
     object.  The symbolic constants used here are defined
     in the header file <filename>libpq/libpq-fs.h</filename>.
     The access type (read, write, or both) is controlled by
     or'ing together the bits <symbol>INV_READ</symbol>  and
     <symbol>INV_WRITE</symbol>.  The low-order sixteen bits of the mask have
     historically been used at Berkeley to designate the storage  manager  number on which the large object
     should reside.  These bits should always be zero now.  (The access type
     does not actually do anything anymore either, but one or both flag bits
     must be set to avoid an error.)
d121 8
d137 29
d215 7
a221 5
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
     object  to  open.   The  <parameter>mode</parameter>  bits control whether the
     object is opened  for  reading  (<symbol>INV_READ</>),  writing (<symbol>INV_WRITE</symbol>),  or
     both.
     A  large  object cannot be opened before it is created.
d229 25
a253 1
</para>
d372 1
d386 2
@


1.35
log
@Some more small improvements in response to 7.4 interactive docs comments.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.34 2004/12/28 22:47:15 tgl Exp $
d54 5
a58 3
    <indexterm><primary>TOAST</></>
    <indexterm><primary>sliced bread</><see>TOAST</></indexterm>
    <productname>PostgreSQL 7.1</productname> introduced a mechanism
@


1.34
log
@More minor updates and copy-editing.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.33 2003/11/29 19:51:37 pgsql Exp $
d125 5
a129 3
     should reside.  These
     bits should always be zero now.
     The return value is the OID that was assigned to the new large object.
d135 1
a135 1
inv_oid = lo_creat(INV_READ|INV_WRITE);
d152 2
a153 1
     The return value is the OID that was assigned to the new large object.
d170 5
a174 5
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
     object  to  export  and the <parameter>filename</parameter> argument specifies
     the operating system name of the file.
     Note that the file is written by the client interface library, not by
     the server.
d182 1
a182 1
     To open an existing large object, call
d192 5
a196 4
     <function>lo_open</function> returns a large object descriptor
     for later use in <function>lo_read</function>, <function>lo_write</function>,
     <function>lo_lseek</function>, <function>lo_tell</function>, and
     <function>lo_close</function>.  The descriptor is only valid for
d198 1
d254 1
a254 1
     the new location pointer.
d302 1
a302 2
     large object to remove.  In the event of an error, the return
     value is negative.
a305 1

d311 12
a322 8
<para>
     There are two built-in server-side functions,
     <function>lo_import</function><indexterm><primary>lo_import</></>
     and
     <function>lo_export</function>,<indexterm><primary>lo_export</></>
     for large object access, which are available for use in
     <acronym>SQL</acronym> commands.  Here is an example of their
     use:
d329 4
d339 1
a339 1
</para>
d341 11
a351 7
<para>
These functions read and write files in the server's file system, using the
permissions of the database's owning user.  Therefore, their use is restricted
to superusers.  (In contrast, the client-side import and export functions
read and write files in the client's file system, using the permissions of
the client program.  Their use is not restricted.)
</para>
@


1.33
log
@
$Header: -> $PostgreSQL Changes ...
@
text
@d2 1
a2 1
$PostgreSQL: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.32 2003/11/12 22:47:47 petere Exp $
d12 5
a16 9
    In <productname>PostgreSQL</productname> releases prior to 7.1,
    the size of any row in the database could not exceed the size of a
    data page.  Since the size of a data page is 8192 bytes (the
    default, which can be raised up to 32768), the upper limit on the
    size of a data value was relatively low. To support the storage of
    larger atomic values, <productname>PostgreSQL</productname>
    provided and continues to provide a large object interface.  This
    interface provides file-oriented access to user data that is stored in
    a special large-object structure.
d58 7
a64 4
    data rows to be much larger than individual data pages.  This
    makes the large object interface partially obsolete.  One
    remaining advantage of the large object interface is that it allows values up
    to 2 GB in size, whereas <acronym>TOAST</acronym> can only handle 1 GB.
d119 1
a119 1
     object.  The symbolic constants listed here are defined
d151 3
d169 3
a171 1
     the operating system name name of the file.
d207 1
a207 1
     to large object <parameter>fd</>.  The <parameter>fd</parameter>
d224 1
a224 1
     <parameter>len</parameter> bytes from large object
d234 1
a234 1
<title>Seeking on a Large Object</title>
d237 2
a238 2
     To change the current read or write location on a large
     object, call
d243 1
a243 1
     current location pointer for the large object described by
d257 1
a257 1
     To obtain the current read or write location of a large object,
d271 1
a271 1
     A large object may be closed by calling
@


1.32
log
@Documentation cleanup
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.31 2003/11/01 01:56:29 petere Exp $
@


1.31
log
@Spell checking, consistent terminology.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.30 2003/08/31 17:32:19 petere Exp $
d302 1
a302 1
<title>Server-side Functions</title>
@


1.31.2.1
log
@Documentation cleanup
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.31 2003/11/01 01:56:29 petere Exp $
d302 1
a302 1
<title>Server-Side Functions</title>
@


1.30
log
@Add/edit index entries.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.29 2003/06/21 21:51:33 tgl Exp $
d327 1
a327 1
These functions read and write files in the server's filesystem, using the
d330 1
a330 1
read and write files in the client's filesystem, using the permissions of
@


1.29
log
@Update libpq to make new features of FE/BE protocol available to
client applications.  Some editorial work on libpq.sgml, too.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.28 2003/03/13 01:30:28 petere Exp $
d116 1
d147 2
a148 1
    <replaceable class="parameter">filename</replaceable> 
d164 1
d179 1
d201 7
a207 4
     writes <parameter>len</parameter> bytes from <parameter>buf</parameter> to large object <parameter>fd</>.   The <parameter>fd</parameter>
     argument must have been returned by a previous <function>lo_open</function>.
     The number of bytes actually written is  returned.   In
     the event of an error, the return value is negative.
d219 7
a225 4
     reads <parameter>len</parameter> bytes from large object <parameter>fd</parameter> into <parameter>buf</parameter>. The  <parameter>fd</parameter>
     argument must have been returned by a previous <function>lo_open</function>.
     The number of bytes actually read is returned. In
     the event of an error, the return value is negative.
d238 8
a245 4
     This function moves the current location pointer for the
     large object described by <parameter>fd</> to the new location specified 
     by <parameter>offset</>.  The valid values for <parameter>whence</> are
     <symbol>SEEK_SET</> (seek from object start), <symbol>SEEK_CUR</> (seek from current position), and <symbol>SEEK_END</> (seek from object end).  The return value is the new location pointer.
d258 2
a259 1
     If there is an error, the return value is negative.
d271 4
a274 3
     where  <parameter>fd</>  is  a  large  object  descriptor returned by
     <function>lo_open</function>.  On success, <function>lo_close</function>
      returns zero.  On error, the return value is negative.
d291 4
a294 2
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
     object  to  remove.  In the event of an error, the return value is negative.
d305 7
a311 5
     There  are two built-in server-side functions, <function>lo_import</function>
     and <function>lo_export</function>, for large object access, which are available for use
    in  <acronym>SQL</acronym>
     commands.
     Here is an example of their use:
@


1.29.2.1
log
@Update this branch to match CVS head, includes WIN32 improvements.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.30 2003/08/31 17:32:19 petere Exp $
a115 1
     <indexterm><primary>lo_creat</></>
d146 1
a146 2
     <indexterm><primary>lo_import</></>
     <replaceable class="parameter">filename</replaceable> 
a161 1
     <indexterm><primary>lo_export</></>
a175 1
     <indexterm><primary>lo_open</></>
d197 4
a200 7
     <indexterm><primary>lo_write</></> writes
     <parameter>len</parameter> bytes from <parameter>buf</parameter>
     to large object <parameter>fd</>.  The <parameter>fd</parameter>
     argument must have been returned by a previous
     <function>lo_open</function>.  The number of bytes actually
     written is returned.  In the event of an error, the return value
     is negative.
d212 4
a215 7
     <indexterm><primary>lo_read</></> reads
     <parameter>len</parameter> bytes from large object
     <parameter>fd</parameter> into <parameter>buf</parameter>. The
     <parameter>fd</parameter> argument must have been returned by a
     previous <function>lo_open</function>.  The number of bytes
     actually read is returned. In the event of an error, the return
     value is negative.
d228 4
a231 8
     <indexterm><primary>lo_lseek</></> This function moves the
     current location pointer for the large object described by
     <parameter>fd</> to the new location specified by
     <parameter>offset</>.  The valid values for <parameter>whence</>
     are <symbol>SEEK_SET</> (seek from object start),
     <symbol>SEEK_CUR</> (seek from current position), and
     <symbol>SEEK_END</> (seek from object end).  The return value is
     the new location pointer.
d244 1
a244 2
     <indexterm><primary>lo_tell</></> If there is an error, the
     return value is negative.
d256 3
a258 4
     <indexterm><primary>lo_close</></> where <parameter>fd</> is a
     large object descriptor returned by <function>lo_open</function>.
     On success, <function>lo_close</function> returns zero.  On
     error, the return value is negative.
d275 2
a276 4
     <indexterm><primary>lo_unlink</></> The
     <parameter>lobjId</parameter> argument specifies the OID of the
     large object to remove.  In the event of an error, the return
     value is negative.
d287 5
a291 7
     There are two built-in server-side functions,
     <function>lo_import</function><indexterm><primary>lo_import</></>
     and
     <function>lo_export</function>,<indexterm><primary>lo_export</></>
     for large object access, which are available for use in
     <acronym>SQL</acronym> commands.  Here is an example of their
     use:
@


1.28
log
@Big editing for consistent content and presentation.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/lobj.sgml,v 1.27 2002/04/18 14:28:14 momjian Exp $
d184 2
a185 1
     <function>lo_close</function>.
d260 5
d304 8
@


1.27
log
@Correct documention of lo_unlink return value as int, not Oid.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.26 2002/01/20 22:19:56 petere Exp $
a10 3
  <sect1 id="lo-intro">
   <title>Introduction</title>

d19 2
a20 2
    interface provides file-oriented access to user data that has been
    declared to be a large object.
d24 14
d64 2
a65 15
    remaining advantage of the large object interface is that it
    allows random access to the data, i.e., the ability to read or
    write small chunks of a large value.  It is planned to equip
    <acronym>TOAST</acronym> with such functionality in the future.
   </para>

   <para>
    This section describes the implementation and the programming and
    query language interfaces to <productname>PostgreSQL</productname>
    large object data.  We use the <application>libpq</application> C
    library for the examples in this section, but most programming
    interfaces native to <productname>PostgreSQL</productname> support
    equivalent functionality.  Other interfaces may use the large
    object interface internally to provide generic support for large
    values.  This is not described here.
d76 1
a76 1
    tuples in the database.  A B-tree index guarantees fast
d83 1
a83 1
   <title>Interfaces</title>
d86 13
a98 17
    The  facilities  <productname>PostgreSQL</productname> provides  to
    access large objects,  both  in  the backend as part of user-defined
    functions or the front end as part  of  an  application
    using  the   interface, are described below. For users
    familiar with <productname>POSTGRES 4.2</productname>,
    <productname>PostgreSQL</productname> has a new set of
    functions  providing  a  more  coherent  interface.

    <note>
     <para>
      All large object manipulation <emphasis>must</emphasis> take
      place within an SQL transaction. This requirement is strictly
      enforced as of <productname>PostgreSQL 6.5</>, though it has been an
      implicit requirement in previous versions, resulting in
      misbehavior if ignored.
     </para>
    </note>
d102 4
a105 19
    The  <productname>PostgreSQL</productname>  large  object interface is modeled after
    the <acronym>Unix</acronym>  file-system  interface,  with  analogues  of
    <function>open(2)</function>,  <function>read(2)</function>,
    <function>write(2)</function>,
    <function>lseek(2)</function>, etc.  User 
    functions call these routines to retrieve only the data  of
    interest  from a large object.  For example, if a large
    object type called <type>mugshot</type>  existed  that  stored  
    photographs  of  faces, then a function called <function>beard</function> could
    be declared on <type>mugshot</type> data.  <function>beard</> could look  at  the
    lower third of a photograph, and determine the color of
    the beard that appeared  there,  if  any.   The  entire
    large-object value need not be buffered, or even 
    examined, by the <function>beard</function> function.
    Large objects may be accessed from dynamically-loaded <acronym>C</acronym>
    functions  or  database  client  programs that link the
    library.  <productname>PostgreSQL</productname> provides a set of routines that 
    support opening, reading, writing, closing, and seeking on
    large objects.
d112 1
a112 1
     The routine
d114 1
a114 1
Oid lo_creat(PGconn *<replaceable class="parameter">conn</replaceable>, int <replaceable class="parameter">mode</replaceable>)
d127 5
a131 1
     The commands below create a large object:
d144 1
a144 1
Oid lo_import(PGconn *<replaceable class="parameter">conn</replaceable>, const char *<replaceable class="parameter">filename</replaceable>)
d149 1
d160 1
a160 1
int lo_export(PGconn *<replaceable class="parameter">conn</replaceable>, Oid <replaceable class="parameter">lobjId</replaceable>, const char *<replaceable class="parameter">filename</replaceable>)
d174 1
a174 1
int lo_open(PGconn *conn, Oid lobjId, int mode)
d192 4
a195 4
     The routine
<programlisting>
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
</programlisting>
d207 4
a210 4
     The routine
<programlisting>
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
</programlisting>
d224 4
a227 4
<programlisting>
int lo_lseek(PGconn *conn, int fd, int offset, int whence)
</programlisting>
     This routine moves the current location pointer for the
d230 14
a243 1
     <symbol>SEEK_SET</>, <symbol>SEEK_CUR</>, and <symbol>SEEK_END</>.
d252 3
a254 3
<programlisting>
int lo_close(PGconn *conn, int fd)
</programlisting>
d267 1
a267 1
int lo_unlink(PGconn *<replaceable class="parameter">conn</replaceable>, Oid lobjId)
d278 1
a278 1
<title>Server-side Built-in Functions</title>
d281 2
a282 2
     There  are two built-in registered functions, <function>lo_import</function>
     and <function>lo_export</function> which  are  convenient  for  use
d284 2
a285 2
     queries.
     Here is an example of their use
d301 2
a302 2
<sect1 id="lo-libpq">
<title>Accessing Large Objects from <application>Libpq</application></title>
d309 1
a309 1
     benefit.  This program can be found in
a310 3
     Frontend applications which use the large object interface  
     in  <application>libpq</application>  should   include   the   header   file
     <filename>libpq/libpq-fs.h</filename> and link with the <application>libpq</application> library.
d314 1
a314 1
   <title>Large Objects with <application>Libpq</application> Example Program</title>
@


1.26
log
@Spell-check and markup police
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.25 2002/01/07 02:29:12 petere Exp $
d270 1
a270 1
Oid lo_unlink(PGconn *<replaceable class="parameter">conn</replaceable>, Oid lobjId)
d273 1
a273 1
     object  to  remove.
@


1.25
log
@Editorial review
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.24 2001/11/12 19:19:39 petere Exp $
d178 1
a178 1
     The <parameter>lobjId</parameter> argument specifies  the  Oid  of  the  large
d192 1
a192 1
     The <parameter>lobjId</parameter> argument specifies  the  Oid  of  the  large
d272 1
a272 1
     The <parameter>lobjId</parameter> argument specifies  the  Oid  of  the  large
@


1.24
log
@Add some more index entries.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.23 2001/10/09 18:46:00 petere Exp $
d109 1
a109 1
    the <acronym>Unix</acronym>  file  system  interface,  with  analogues  of
d116 2
a117 2
    photographs  of  faces, then a function called beard could
    be declared on <type>mugshot</type> data.  Beard could look  at  the
d120 2
a121 2
    large  object value need not be buffered, or even 
    examined, by the beard function.
d143 1
a143 1
     OR'ing together the bits <symbol>INV_READ</symbol>  and
d159 1
a159 1
     To import a <acronym>UNIX</acronym> file as a large object, call
d164 1
a164 1
     specifies the  <acronym>Unix</acronym>  path name  of
d174 1
a174 1
     into <acronym>UNIX</acronym> file, call
d180 1
a180 1
     the <acronym>UNIX</acronym> path name of the file.
d194 1
a194 1
     object is opened  for  reading  (<symbol>INV_READ</>),  writing  or
d244 3
a246 3
     large object described by fd to the new location specified 
     by offset.  The valid values for whence are
     SEEK_SET, SEEK_CUR, and SEEK_END.
d258 1
a258 1
     where  fd  is  a  large  object  descriptor returned by
d284 2
a285 2
     There  are two built-in registered functions, <acronym>lo_import</acronym>
     and <acronym>lo_export</acronym> which  are  convenient  for  use
d298 1
a298 1
SELECT lo_export(image.raster, '/tmp/motd') from image
d308 1
a308 1
     Below is a sample program which shows how the large object  
d311 1
a311 1
     commented out but are left in the source for  the  readers
d313 1
a313 3
<filename>
../src/test/examples
</filename>
a317 4
</sect1>

<sect1 id="lo-example">
<title>Example Program</title>
d319 1
a319 1
  <example>
@


1.23
log
@Bunch of copy fitting and style sheet tweakage to get decent looking print
output (from pdfjadetex).  Also updated instructions to install documentation
processing toolchain.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.22 2001/09/16 22:53:52 petere Exp $
d8 3
d47 2
@


1.22
log
@Update intro in face of TOAST.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.21 2001/09/15 16:08:59 petere Exp $
a328 4
 *
 *
 * IDENTIFICATION
 *    /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
@


1.21
log
@Markup examples as examples.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.20 2001/09/13 15:55:23 petere Exp $
d8 55
a62 36
  <para>
   In <productname>Postgres</productname>,
   data values are stored in tuples and 
   individual tuples cannot span data pages. Since the size of
   a data page is 8192 bytes, the upper limit on the  size
   of a data value is relatively low. To support the storage 
   of larger atomic values, 
   <productname>Postgres</productname> provides a  large
   object   interface.    This  interface  provides  file
   oriented access to user data that has been declared  to
   be a large type.
   This  section describes the implementation and the 
   programming and query  language  interfaces  to 
   <productname>Postgres</productname>
   large object data.
  </para>

  <sect1 id="lo-history">
   <title>Historical Note</title>

   <para>
    Originally, <productname>Postgres 4.2</productname> supported three standard 
    implementations of large objects: as files external 
    to <productname>Postgres</productname>,  as
    external files managed by <productname>Postgres</productname>, and as data
    stored within the <productname>Postgres</productname> database. It causes  
    considerable confusion among users. As a result, we only 
    support large objects as data stored within  the  <productname>Postgres</productname>
    database  in  <productname>PostgreSQL</productname>.  Even  though it is slower to
    access, it provides stricter data  integrity.
    For historical reasons, this storage scheme is referred to as 
    Inversion large objects. (We will use  Inversion  and  large
    objects  interchangeably to mean the same thing in this
    section.)
    Since <productname>PostgreSQL 7.1</productname> all large objects are placed in
    one system table called <classname>pg_largeobject</classname>.
d64 1
d71 1
a71 1
    The Inversion large object implementation breaks  large
d83 1
a83 1
    The  facilities  <productname>Postgres</productname> provides  to
d87 1
a87 1
    familiar with <productname>Postgres 4.2</productname>,
d95 1
a95 1
      enforced as of Postgres 6.5, though it has been an
d103 1
a103 1
    The  <productname>Postgres</productname>  large  object interface is modeled after
d119 1
a119 1
    library.  <productname>Postgres</productname> provides a set of routines that 
d136 1
a136 2
     in
     <filename>$<envar>PGROOT</envar>/src/backend/libpq/libpq-fs.h</filename>
d138 7
a144 7
     OR'ing together the bits <acronym>INV_READ</acronym>  and
     <acronym>INV_WRITE</acronym>.  The low-order sixteen bits of mask  are
     the  storage  manager  number on which the large object
     should reside.  For sites other  than  Berkeley,  these
     bits should always be zero.
     The commands below create an (Inversion) large object:
     <programlisting>
d146 1
a146 1
     </programlisting>
@


1.20
log
@Replace ASCII-quotes with proper markup.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.19 2001/09/10 21:58:47 petere Exp $
d257 1
a257 1
<title>Built in registered functions</title>
d298 2
a299 2
<sect1 id="lo-sample">
<title>Sample Program</title>
d301 2
a302 1
<para>
d324 2
a325 2
 * importFile *    import file &quot;in_filename&quot; into database as large object &quot;lob
jOid&quot;
d556 1
a556 1
</para>
@


1.19
log
@Markup and spell-check run over Programmer's Guide (rather incomplete still).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.18 2001/09/10 04:15:41 momjian Exp $
d52 1
a52 1
    objects  up  into  "chunks"  and  stores  the chunks in
@


1.18
log
@Remove mention of INV_ARCHIVE.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.17 2001/09/10 03:02:06 ishii Exp $
d43 1
a43 1
    one system table called pg_largeobject.
d90 1
a90 1
    object type called mugshot  existed  that  stored  
d92 1
a92 1
    be declared on mugshot data.  Beard could look  at  the
d113 1
a113 1
     <replaceable class="parameter">mode</replaceable>  is  a  bitmask
d119 1
a119 1
     OR ing together the bits <acronym>INV_READ</acronym>  and
d140 1
a140 1
     specifies the  <acronym>Unix</acronym>  pathname  of
d154 3
a156 3
     The lobjId argument specifies  the  Oid  of  the  large
     object  to  export  and the filename argument specifies
     the <acronym>UNIX</acronym> pathname of the file.
d168 3
a170 3
     The lobjId argument specifies  the  Oid  of  the  large
     object  to  open.   The  mode  bits control whether the
     object is opened  for  reading  INV_READ),  writing  or
d188 1
a188 1
     writes len bytes from buf to large object fd.   The  fd
d203 1
a203 1
     reads len bytes from large object fd into buf. The  fd
d248 1
a248 1
     The lobjId argument specifies  the  Oid  of  the  large
d281 1
a281 1
<title>Accessing Large Objects from LIBPQ</title>
d286 1
a286 1
     in  LIBPQ  can  be used.  Parts of the program are 
d293 2
a294 2
     in  LIBPQ  should   include   the   header   file
     libpq/libpq-fs.h and link with the libpq library.
@


1.17
log
@fix typo.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.16 2001/02/09 19:24:09 momjian Exp $
d120 1
a120 5
     <acronym>INV_WRITE</acronym>.   If
     the large object should be archived -- that is, if 
     historical versions of it should be moved periodically  to
     a  special archive relation -- then the <acronym>INV_ARCHIVE</acronym> bit
     should be set.  The low-order sixteen bits of mask  are
d126 1
a126 1
inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE);
@


1.16
log
@Large object manual updates.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.15 2001/01/20 00:05:54 momjian Exp $
d207 1
a207 1
     reads len bytes from large object fd into byf. The  fd
@


1.15
log
@In the Programmer's Guide, the sample code for accessing large objects
from libpq has two functions with memory leaks.

The functions pickout() and overwrite() malloc space for buf which is
never freed.

See
http://www.postgresql.org/users-lounge/docs/7.0/programmer/largeobjects3207.htm

This problem is also in the 6.5 docs at
http://www.postgresql.org/users-lounge/docs/6.5/programmer/x3184.htm

Nishad Prakash
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.14 2000/12/21 22:55:27 petere Exp $
d42 2
@


1.14
log
@Get rid of the little "v"s in front of version numbers, substituting the
full word "version" where appropriate.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.13 2000/09/29 20:21:34 petere Exp $
d319 2
a320 2
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
d325 2
a326 1
 * importFile *    import file "in_filename" into database as large object "lobjOid"
d329 2
a330 1
Oid importFile(PGconn *conn, char *filename)
d332 6
a337 5
    Oid lobjId;
    int lobj_fd;
    char buf[BUFSIZE];
    int nbytes, tmp;
    int fd;
d343 3
a345 2
    if (fd &lt; 0)  {   /* error */
     fprintf(stderr, "can't open unix file %s\n", filename);
d351 3
a353 4
    lobjId = lo_creat(conn, INV_READ|INV_WRITE);
    if (lobjId == 0) {
     fprintf(stderr, "can't create large object\n");
    }
d356 1
d360 5
a364 5
    while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) {
     tmp = lo_write(conn, lobj_fd, buf, nbytes);
     if (tmp &lt; nbytes) {
         fprintf(stderr, "error while reading large object\n");
     }
d373 2
a374 1
void pickout(PGconn *conn, Oid lobjId, int start, int len)
d376 4
a379 4
    int lobj_fd;
    char* buf;
    int nbytes;
    int nread;
d382 4
a385 3
    if (lobj_fd &lt; 0) {
     fprintf(stderr,"can't open large object %d\n",
          lobjId);
d389 1
a389 1
    buf = malloc(len+1);
d392 6
a397 5
    while (len - nread &gt; 0) {
     nbytes = lo_read(conn, lobj_fd, buf, len - nread);
     buf[nbytes] = ' ';
     fprintf(stderr,"&gt;&gt;&gt; %s", buf);
     nread += nbytes;
d399 2
a400 1
    fprintf(stderr,"\n");
d404 2
a405 1
void overwrite(PGconn *conn, Oid lobjId, int start, int len)
d407 5
a411 5
    int lobj_fd;
    char* buf;
    int nbytes;
    int nwritten;
    int i;
d414 4
a417 3
    if (lobj_fd &lt; 0) {
     fprintf(stderr,"can't open large object %d\n",
          lobjId);
d421 1
a421 1
    buf = malloc(len+1);
d423 2
a424 2
    for (i=0;i&lt;len;i++)
     buf[i] = 'X';
d428 4
a431 3
    while (len - nwritten &gt; 0) {
     nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
     nwritten += nbytes;
d433 2
a434 1
    fprintf(stderr,"\n");
d439 1
a439 1
 * exportFile *    export large object "lobjOid" to file "out_filename"
d442 2
a443 1
void exportFile(PGconn *conn, Oid lobjId, char *filename)
d445 5
a449 4
    int lobj_fd;
    char buf[BUFSIZE];
    int nbytes, tmp;
    int fd;
d452 1
a452 1
     * create an inversion "object"
d455 4
a458 3
    if (lobj_fd &lt; 0) {
     fprintf(stderr,"can't open large object %d\n",
          lobjId);
d464 5
a468 4
    fd = open(filename, O_CREAT|O_WRONLY, 0666);
    if (fd &lt; 0)  {   /* error */
     fprintf(stderr, "can't open unix file %s\n",
          filename);
d474 8
a481 6
    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) {
     tmp = write(fd, buf, nbytes);
        if (tmp &lt; nbytes) {
         fprintf(stderr,"error while writing %s\n",
              filename);
     }
d491 1
a491 1
exit_nicely(PGconn* conn)
d493 2
a494 2
  PQfinish(conn);
  exit(1);
d500 12
a511 10
    char *in_filename, *out_filename;
    char *database;
    Oid lobjOid;
    PGconn *conn;
    PGresult *res;

    if (argc != 4) {
     fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
          argv[0]);
     exit(1);
d524 5
a528 4
    if (PQstatus(conn) == CONNECTION_BAD) {
     fprintf(stderr,"Connection to database '%s' failed.\n", database);
     fprintf(stderr,"%s",PQerrorMessage(conn));
     exit_nicely(conn);
d531 1
a531 1
    res = PQexec(conn, "begin");
d534 1
a534 1
    printf("importing file %s\n", in_filename);
d538 1
a538 1
    printf("as large object %d.\n", lobjOid);
d540 1
a540 1
    printf("picking out bytes 1000-2000 of the large object\n");
d543 1
a543 1
    printf("overwriting bytes 1000-2000 of the large object with X's\n");
d547 1
a547 1
    printf("exporting large object to file %s\n", out_filename);
d549 1
a549 1
    lo_export(conn, lobjOid,out_filename);
d551 1
a551 1
    res = PQexec(conn, "end");
@


1.13
log
@Add `id' attributes to all `chapter' and `sect1' tags, to generate useful
names for the HTML files (e.g., not x4856.htm).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.12 2000/05/15 12:42:23 momjian Exp $
d73 1
a73 1
      enforced as of Postgres v6.5, though it has been an
@


1.12
log
@Add mention of lo_unlink to manual
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.11 2000/05/02 20:01:52 thomas Exp $
d25 1
a25 1
  <sect1>
d45 1
a45 1
  <sect1>
d57 1
a57 1
  <sect1>
d258 1
a258 1
<sect1>
d282 1
a282 1
<sect1>
d300 1
a300 1
<sect1>
@


1.11
log
@Fixups in content and markup for 7.0 release.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.10 2000/03/31 03:27:41 thomas Exp $
d241 15
@


1.10
log
@Minor markup changes. Refer to (".../catalog") in the emacs hints.
@
text
@d2 1
a2 1
$Header$
d291 229
a519 229
          *
          * testlo.c--
          *    test using large objects with libpq
          *
          * Copyright (c) 1994, Regents of the University of California
          *
          *
          * IDENTIFICATION
          *    /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
          *
          *--------------------------------------------------------------
          */
         #include &lt;stdio.h&gt;
         #include "libpq-fe.h"
         #include "libpq/libpq-fs.h"

         #define BUFSIZE          1024

         /*
          * importFile *    import file "in_filename" into database as large object "lobjOid"
          *
          */
         Oid importFile(PGconn *conn, char *filename)
         {
             Oid lobjId;
             int lobj_fd;
             char buf[BUFSIZE];
             int nbytes, tmp;
             int fd;

             /*
              * open the file to be read in
              */
             fd = open(filename, O_RDONLY, 0666);
             if (fd &lt; 0)  {   /* error */
              fprintf(stderr, "can't open unix file %s\n", filename);
             }

             /*
              * create the large object
              */
             lobjId = lo_creat(conn, INV_READ|INV_WRITE);
             if (lobjId == 0) {
              fprintf(stderr, "can't create large object\n");
             }

             lobj_fd = lo_open(conn, lobjId, INV_WRITE);
             /*
              * read in from the Unix file and write to the inversion file
              */
             while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) {
              tmp = lo_write(conn, lobj_fd, buf, nbytes);
              if (tmp &lt; nbytes) {
                  fprintf(stderr, "error while reading large object\n");
              }
             }

             (void) close(fd);
             (void) lo_close(conn, lobj_fd);

             return lobjId;
         }

         void pickout(PGconn *conn, Oid lobjId, int start, int len)
         {
             int lobj_fd;
             char* buf;
             int nbytes;
             int nread;

             lobj_fd = lo_open(conn, lobjId, INV_READ);
             if (lobj_fd &lt; 0) {
              fprintf(stderr,"can't open large object %d\n",
                   lobjId);
             }

             lo_lseek(conn, lobj_fd, start, SEEK_SET);
             buf = malloc(len+1);

             nread = 0;
             while (len - nread &gt; 0) {
              nbytes = lo_read(conn, lobj_fd, buf, len - nread);
              buf[nbytes] = ' ';
              fprintf(stderr,"&gt;&gt;&gt; %s", buf);
              nread += nbytes;
             }
             fprintf(stderr,"\n");
             lo_close(conn, lobj_fd);
         }

         void overwrite(PGconn *conn, Oid lobjId, int start, int len)
         {
             int lobj_fd;
             char* buf;
             int nbytes;
             int nwritten;
             int i;

             lobj_fd = lo_open(conn, lobjId, INV_READ);
             if (lobj_fd &lt; 0) {
              fprintf(stderr,"can't open large object %d\n",
                   lobjId);
             }

             lo_lseek(conn, lobj_fd, start, SEEK_SET);
             buf = malloc(len+1);

             for (i=0;i&lt;len;i++)
              buf[i] = 'X';
             buf[i] = ' ';

             nwritten = 0;
             while (len - nwritten &gt; 0) {
              nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
              nwritten += nbytes;
             }
             fprintf(stderr,"\n");
             lo_close(conn, lobj_fd);
         }

         /*
          * exportFile *    export large object "lobjOid" to file "out_filename"
          *
          */
         void exportFile(PGconn *conn, Oid lobjId, char *filename)
         {
             int lobj_fd;
             char buf[BUFSIZE];
             int nbytes, tmp;
             int fd;

             /*
              * create an inversion "object"
              */
             lobj_fd = lo_open(conn, lobjId, INV_READ);
             if (lobj_fd &lt; 0) {
              fprintf(stderr,"can't open large object %d\n",
                   lobjId);
             }

             /*
              * open the file to be written to
              */
             fd = open(filename, O_CREAT|O_WRONLY, 0666);
             if (fd &lt; 0)  {   /* error */
              fprintf(stderr, "can't open unix file %s\n",
                   filename);
             }

             /*
              * read in from the Unix file and write to the inversion file
              */
             while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) {
              tmp = write(fd, buf, nbytes);
                 if (tmp &lt; nbytes) {
                  fprintf(stderr,"error while writing %s\n",
                       filename);
              }
             }

             (void) lo_close(conn, lobj_fd);
             (void) close(fd);

             return;
         }

         void
         exit_nicely(PGconn* conn)
         {
           PQfinish(conn);
           exit(1);
         }

         int
         main(int argc, char **argv)
         {
             char *in_filename, *out_filename;
             char *database;
             Oid lobjOid;
             PGconn *conn;
             PGresult *res;

             if (argc != 4) {
              fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
                   argv[0]);
              exit(1);
             }

             database = argv[1];
             in_filename = argv[2];
             out_filename = argv[3];

             /*
              * set up the connection
              */
             conn = PQsetdb(NULL, NULL, NULL, NULL, database);

             /* check to see that the backend connection was successfully made */
             if (PQstatus(conn) == CONNECTION_BAD) {
              fprintf(stderr,"Connection to database '%s' failed.\n", database);
              fprintf(stderr,"%s",PQerrorMessage(conn));
              exit_nicely(conn);
             }

             res = PQexec(conn, "begin");
             PQclear(res);

             printf("importing file %s\n", in_filename);
         /*  lobjOid = importFile(conn, in_filename); */
             lobjOid = lo_import(conn, in_filename);
         /*
             printf("as large object %d.\n", lobjOid);

             printf("picking out bytes 1000-2000 of the large object\n");
             pickout(conn, lobjOid, 1000, 1000);

             printf("overwriting bytes 1000-2000 of the large object with X's\n");
             overwrite(conn, lobjOid, 1000, 1000);
         */

             printf("exporting large object to file %s\n", out_filename);
         /*    exportFile(conn, lobjOid, out_filename); */
             lo_export(conn, lobjOid,out_filename);

             res = PQexec(conn, "end");
             PQclear(res);
             PQfinish(conn);
             exit(0);
         }
@


1.9
log
@Fix " to ' on lobj docs.
@
text
@d1 4
d528 1
a528 1
mode: sgml
d538 1
a538 1
sgml-local-catalogs:"/usr/lib/sgml/catalog"
@


1.8
log
@Update for documentation in libpq changes.
@
text
@d257 1
a257 1
SELECT lo_export(image.raster, "/tmp/motd") from image
@


1.7
log
@Expunge "UNIX" in favor of "Unix".
A few other changes, but I forget what :(
@
text
@d103 1
a103 2

     <synopsis>
d105 1
a105 2
     </synopsis>

d133 4
a136 4
     To import a Unix file as a large object, call
     <synopsis>
Oid lo_import(PGconn *<replaceable class="parameter">conn</replaceable>, text *<replaceable class="parameter">filename</replaceable>)
     </synopsis>
d148 4
a151 4
     into <acronym>Unix</acronym> file, call
     <synopsis>
int lo_export(PGconn *<replaceable class="parameter">conn</replaceable>, Oid <replaceable class="parameter">lobjId</replaceable>, text *<replaceable class="parameter">filename</replaceable>)
     </synopsis>
d154 1
a154 1
     the <acronym>Unix</acronym> pathname of the file.
d163 3
a165 3
<programlisting>
int lo_open(PGconn *conn, Oid lobjId, int mode, ...)
</programlisting>
d171 4
a174 2
     lo_open returns a large object descriptor for later use
     in  lo_read, lo_write, lo_lseek, lo_tell, and lo_close.
d184 1
a184 1
int lo_write(PGconn *conn, int fd, char *buf, int len)
d187 1
a187 1
     argument must have been returned by a previous lo_open.
d194 15
d219 2
a220 2
     by offset.  The valid values  for  .i  whence  are
     SEEK_SET SEEK_CUR and SEEK_END.
d233 2
a234 2
     lo_open.  On success, <acronym>lo_close</acronym> returns zero.  On error,
     the return value is negative.
@


1.6
log
@Minor updates for release.
@
text
@d16 1
a16 1
   programmatic and query  language  interfaces  to 
d21 2
a22 2
<sect1>
<title>Historical Note</title>
d24 38
a61 38
<para>
     Originally, <productname>Postgres 4.2</productname> supported three standard 
     implementations of large objects: as files external 
     to <productname>Postgres</productname>,  as
 <acronym>ym>U</acronym>ym>  files managed by <productname>Postgres</productname>, and as data
     stored within the <productname>Postgres</productname> database. It causes  
     considerable confusion among users. As a result, we only 
     support large objects as data stored within  the  <productname>Postgres</productname>
     database  in  <productname>PostgreSQL</productname>.  Even  though it is slower to
     access, it provides stricter data  integrity.
     For historical reasons, this storage scheme is referred to as 
     Inversion large objects. (We will use  Inversion  and  large
     objects  interchangeably to mean the same thing in this
     section.)
</para>
</sect1>

<sect1>
<title>Inversion Large Objects</title>

<para>
     The Inversion large object implementation breaks  large
     objects  up  into  "chunks"  and  stores  the chunks in
     tuples in the database.  A B-tree index guarantees fast
     searches for the correct chunk number when doing random
     access reads and writes.
</para>
</sect1>

<sect1>
<title>Large Object Interfaces</title>

<para>
     The  facilities  <productname>Postgres</productname>  provides  to  access   large
     objects,  both  in  the backend as part of user-defined
     functions or the front end as part  of  an  application
     using  the   interface, are described below. (For users
     familiar with <productname>Postgres 4.2</productname>,
d63 1
a63 24
     functions  providing  a  more  coherent  interface. The
     interface is the same for  dynamically-loaded  C  
     functions as well as for XXX LOST TEXT? WHAT SHOULD GO HERE??.

     The  <productname>Postgres</productname>  large  object interface is modeled after
     the <acronym>UNIX</acronym>  file  system  interface,  with  analogues  of
     <function>open(2)</function>,  <function>read(2)</function>,
<function>write(2)</function>,
 <function>lseek(2)</function>, etc.  User 
     functions call these routines to retrieve only the data  of
     interest  from a large object.  For example, if a large
     object type called mugshot  existed  that  stored  
     photographs  of  faces, then a function called beard could
     be declared on mugshot data.  Beard could look  at  the
     lower third of a photograph, and determine the color of
     the beard that appeared  there,  if  any.   The  entire
     large  object value need not be buffered, or even 
     examined, by the beard function.
     Large objects may be accessed from dynamically-loaded <acronym>C</acronym>
     functions  or  database  client  programs that link the
     library.  <productname>Postgres</productname> provides a set of routines that 
     support opening, reading, writing, closing, and seeking on
     large objects.
</para>
d65 32
a96 2
<sect2>
<title>Creating a Large Object</title>
d98 4
a101 1
<para>
d103 7
a109 4
<programlisting>
Oid lo_creat(PGconn *conn, int mode)
</programlisting>
     creates a new large  object.  The  mode  is  a  bitmask
d113 1
a113 3
<filename>
PGROOT/src/backend/libpq/libpq-fs.h
</filename>
d116 1
a116 1
<acronym>INV_WRITE</acronym>.   If
d125 1
a125 1
<programlisting>
d127 14
a140 14
</programlisting>
</para>
</sect2>

<sect2>
<title>Importing a Large Object</title>

<para>
To import a <acronym>UNIX</acronym> file as
     a large object, call
<programlisting>
Oid lo_import(PGconn *conn, text *filename)
</programlisting>
     The filename argument specifies the  <acronym>UNIX</acronym>  pathname  of
d142 2
a143 2
</para>
</sect2>
d145 2
a146 2
<sect2>
<title>Exporting a Large Object</title>
d148 6
a153 6
<para>
To export a large object
     into <acronym>UNIX</acronym> file, call
<programlisting>
int lo_export(PGconn *conn, Oid lobjId, text *filename)
</programlisting>
d156 3
a158 3
     the <acronym>UNIX</acronym> pathname of the file.
</para>
</sect2>
d160 2
a161 2
<sect2>
<title>Opening an Existing Large Object</title>
d163 1
a163 1
<para>
@


1.5
log
@grammar cleanup
@
text
@d1 2
a2 2
<Chapter Id="largeObjects">
<Title>Large Objects</Title>
d4 16
a19 13
<Para>
     In <ProductName>Postgres</ProductName>, data values are stored in tuples and 
     individual tuples cannot span data pages. Since the size of
     a data page is 8192 bytes, the upper limit on the  size
     of a data value is relatively low. To support the storage 
     of larger atomic values, <ProductName>Postgres</ProductName> provides a  large
     object   interface.    This  interface  provides  file
     oriented access to user data that has been declared  to
     be a large type.
     This  section describes the implementation and the 
     programmatic and query  language  interfaces  to  <ProductName>Postgres</ProductName>
     large object data.
</Para>
d21 2
a22 2
<Sect1>
<Title>Historical Note</Title>
d24 2
a25 2
<Para>
     Originally, <ProductName>Postgres 4.2</ProductName> supported three standard 
d27 3
a29 2
     to <ProductName>Postgres</ProductName>,  as  <Acronym>UNIX</Acronym>  files managed by <ProductName>Postgres</ProductName>, and as data
     stored within the <ProductName>Postgres</ProductName> database. It causes  
d31 2
a32 2
     support large objects as data stored within  the  <ProductName>Postgres</ProductName>
     database  in  <ProductName>PostgreSQL</ProductName>.  Even  though it is slower to
d38 2
a39 2
</Para>
</Sect1>
d41 2
a42 2
<Sect1>
<Title>Inversion Large Objects</Title>
d44 1
a44 1
<Para>
d50 2
a51 2
</Para>
</Sect1>
d53 2
a54 2
<Sect1>
<Title>Large Object Interfaces</Title>
d56 2
a57 2
<Para>
     The  facilities  <ProductName>Postgres</ProductName>  provides  to  access   large
d61 2
a62 1
     familiar with <ProductName>Postgres 4.2</ProductName>, <ProductName>PostgreSQL</ProductName> has a new set of
d67 5
a71 4
     The  <ProductName>Postgres</ProductName>  large  object interface is modeled after
     the <Acronym>UNIX</Acronym>  file  system  interface,  with  analogues  of
     <Function>open(2)</Function>,  <Function>read(2)</Function>, <Function>write(2)</Function>,
 <Function>lseek(2)</Function>, etc.  User 
d81 1
a81 1
     Large objects may be accessed from dynamically-loaded <Acronym>C</Acronym>
d83 1
a83 1
     library.  <ProductName>Postgres</ProductName> provides a set of routines that 
d86 1
a86 1
</Para>
d88 2
a89 2
<Sect2>
<Title>Creating a Large Object</Title>
d91 1
a91 1
<Para>
d93 1
a93 1
<ProgramListing>
d95 1
a95 1
</ProgramListing>
d100 1
a100 1
<FileName>
d102 1
a102 1
</FileName>
d104 2
a105 1
     OR ing together the bits <Acronym>INV_READ</Acronym>  and  <Acronym>INV_WRITE</Acronym>.   If
d108 1
a108 1
     a  special archive relation -- then the <Acronym>INV_ARCHIVE</Acronym> bit
d114 1
a114 1
<ProgramListing>
d116 3
a118 3
</ProgramListing>
</Para>
</Sect2>
d120 2
a121 2
<Sect2>
<Title>Importing a Large Object</Title>
d123 2
a124 2
<Para>
To import a <Acronym>UNIX</Acronym> file as
d126 1
a126 1
<ProgramListing>
d128 2
a129 2
</ProgramListing>
     The filename argument specifies the  <Acronym>UNIX</Acronym>  pathname  of
d131 2
a132 2
</Para>
</Sect2>
d134 2
a135 2
<Sect2>
<Title>Exporting a Large Object</Title>
d137 1
a137 1
<Para>
d139 2
a140 2
     into <Acronym>UNIX</Acronym> file, call
<ProgramListing>
d142 1
a142 1
</ProgramListing>
d145 3
a147 3
     the <Acronym>UNIX</Acronym> pathname of the file.
</Para>
</Sect2>
d149 2
a150 2
<Sect2>
<Title>Opening an Existing Large Object</Title>
d152 1
a152 1
<Para>
d154 1
a154 1
<ProgramListing>
d156 1
a156 1
</ProgramListing>
d164 2
a165 2
</Para>
</Sect2>
d167 2
a168 2
<Sect2>
<Title>Writing Data to a Large Object</Title>
d170 1
a170 1
<Para>
d172 1
a172 1
<ProgramListing>
d174 1
a174 1
</ProgramListing>
d179 2
a180 2
</Para>
</Sect2>
d182 2
a183 2
<Sect2>
<Title>Seeking on a Large Object</Title>
d185 1
a185 1
<Para>
d188 1
a188 1
<ProgramListing>
d190 1
a190 1
</ProgramListing>
d195 2
a196 2
</Para>
</Sect2>
d198 2
a199 2
<Sect2>
<Title>Closing a Large Object Descriptor</Title>
d201 1
a201 1
<Para>
d203 1
a203 1
<ProgramListing>
d205 1
a205 1
</ProgramListing>
d207 1
a207 1
     lo_open.  On success, <Acronym>lo_close</Acronym> returns zero.  On error,
d209 1
a209 1
</Para>
d211 1
a211 1
</Sect1>
d213 2
a214 2
<Sect1>
<Title>Built in registered functions</Title>
d216 4
a219 3
<Para>
     There  are two built-in registered functions, <Acronym>lo_import</Acronym>
     and <Acronym>lo_export</Acronym> which  are  convenient  for  use  in  <Acronym>SQL</Acronym>
d222 1
a222 1
<ProgramListing>
d233 3
a235 3
</ProgramListing>
</Para>
</Sect1>
d237 2
a238 2
<Sect1>
<Title>Accessing Large Objects from LIBPQ</Title>
d240 1
a240 1
<Para>
d246 1
a246 1
<FileName>
d248 1
a248 1
</FileName>
d252 2
a253 2
</Para>
</Sect1>
d255 2
a256 2
<Sect1>
<Title>Sample Program</Title>
d258 2
a259 2
<Para>
<ProgramListing>
d490 5
a494 2
</ProgramListing>
</Para>
d496 16
a511 2
</Sect1>
</Chapter>
@


1.4
log
@Clean up to ensure tag completion as required by the newest versions
 of Norm's Modular Style Sheets and jade/docbook.
From Vince Vielhaber <vev@@michvhf.com>.
@
text
@d28 1
a28 1
     database  in  <ProductName>PostgreSQL</ProductName>.  Even  though is is slower to
@


1.3
log
@Minor documentation improvements and markup fixes.
@
text
@d203 1
@


1.2
log
@Add id field to chapter and book tags to allow output file names
 to be meaningful.
@
text
@d287 1
a287 1
              fprintf(stderr, "can't open unix file
d295 1
a295 1
              fprintf(stderr, "can't create large object");
d305 1
a305 1
                  fprintf(stderr, "error while reading
d324 1
a324 1
              fprintf(stderr,"can't open large object %d",
d338 1
a338 1
             fprintf(stderr,"0);
d352 1
a352 1
              fprintf(stderr,"can't open large object %d",
d368 1
a368 1
             fprintf(stderr,"0);
d388 1
a388 1
              fprintf(stderr,"can't open large object %d",
d397 1
a397 1
              fprintf(stderr, "can't open unix file
d407 1
a407 1
                  fprintf(stderr,"error while writing
d435 1
a435 1
              fprintf(stderr, "Usage: %s database_name in_filename out_filename0,
d451 1
a451 1
              fprintf(stderr,"Connection to database '%s' failed.0, database);
d459 1
a459 1
             printf("importing file
d463 1
a463 1
             printf("as large object %d.0, lobjOid);
d465 1
a465 1
             printf("picking out bytes 1000-2000 of the large object0);
d468 1
a468 1
             printf("overwriting bytes 1000-2000 of the large object with X's0);
d472 1
a472 1
             printf("exporting large object to file
@


1.1
log
@SGML source for new documentation.
@
text
@d1 1
a1 1
<Chapter>
@
