lobj.sgml 17.9 KB
Newer Older
1
<!--
2
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.29 2003/06/21 21:51:33 tgl Exp $
3 4
-->

T
Thomas G. Lockhart 已提交
5 6 7
 <chapter id="largeObjects">
  <title id="largeObjects-title">Large Objects</title>

P
Peter Eisentraut 已提交
8 9 10
  <indexterm zone="largeobjects"><primary>large object</></>
  <indexterm><primary>BLOB</><see>large object</></>

11
   <para>
12 13 14 15 16 17 18
    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
19 20
    interface provides file-oriented access to user data that is stored in
    a special large-object structure.
21
   </para>
22

23 24 25 26 27 28 29 30 31 32 33 34 35 36
   <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 may use the large
    object interface internally to provide generic support for large
    values.  This is not described here.
   </para>

  <sect1 id="lo-history">
   <title>History</title>

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
   <para>
    <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
    <classname>pg_largeobject</classname>.
   </para>

   <para>
P
Peter Eisentraut 已提交
58 59
    <indexterm><primary>TOAST</></>
    <indexterm><primary>sliced bread</><see>TOAST</></indexterm>
60 61 62 63
    <productname>PostgreSQL 7.1</productname> introduced a mechanism
    (nicknamed <quote><acronym>TOAST</acronym></quote>) that allows
    data rows to be much larger than individual data pages.  This
    makes the large object interface partially obsolete.  One
64 65
    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.
66 67
   </para>

68 69
  </sect1>

70
  <sect1 id="lo-implementation">
71 72 73
   <title>Implementation Features</title>

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

82
  <sect1 id="lo-interfaces">
83
   <title>Client Interfaces</title>
84 85

   <para>
86 87 88 89 90 91 92 93 94 95 96 97 98
    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.  (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.)
    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.
99 100 101
   </para>

   <para>
102 103 104 105
    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.
106 107 108 109 110 111
   </para>

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

    <para>
112
     The function
113
<synopsis>
114
Oid lo_creat(PGconn *conn, int mode);
115
</synopsis>
116
     creates a new large  object.  
117
     <replaceable class="parameter">mode</replaceable>  is  a  bit mask
118 119
     describing  several  different  attributes  of  the new
     object.  The symbolic constants listed here are defined
120
     in the header file <filename>libpq/libpq-fs.h</filename>.
121
     The access type (read, write, or both) is controlled by
P
Peter Eisentraut 已提交
122
     or'ing together the bits <symbol>INV_READ</symbol>  and
123 124 125 126
     <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.
127 128 129 130 131
     The return value is the OID that was assigned to the new large object.
    </para>

    <para>
     An example:
132
<programlisting>
B
Bruce Momjian 已提交
133
inv_oid = lo_creat(INV_READ|INV_WRITE);
134
</programlisting>
135 136 137 138 139 140 141
    </para>
   </sect2>

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

    <para>
P
Peter Eisentraut 已提交
142
     To import an operating system file as a large object, call
143
<synopsis>
144
Oid lo_import(PGconn *conn, const char *filename);
145
</synopsis>
146
    <replaceable class="parameter">filename</replaceable> 
P
Peter Eisentraut 已提交
147
     specifies the operating system name of
148
     the file to be imported as a large object.
149
     The return value is the OID that was assigned to the new large object.
150 151 152 153 154 155 156 157
    </para>
   </sect2>

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

    <para>
     To export a large object
P
Peter Eisentraut 已提交
158
     into an operating system file, call
159
<synopsis>
160
int lo_export(PGconn *conn, Oid lobjId, const char *filename);
161
</synopsis>
P
Peter Eisentraut 已提交
162
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
163
     object  to  export  and the <parameter>filename</parameter> argument specifies
P
Peter Eisentraut 已提交
164
     the operating system name name of the file.
165 166
    </para>
   </sect2>
167

168 169
   <sect2>
    <title>Opening an Existing Large Object</title>
170

171
    <para>
172
     To open an existing large object, call
173
<synopsis>
174
int lo_open(PGconn *conn, Oid lobjId, int mode);
175
</synopsis>
P
Peter Eisentraut 已提交
176
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
177
     object  to  open.   The  <parameter>mode</parameter>  bits control whether the
P
Peter Eisentraut 已提交
178
     object is opened  for  reading  (<symbol>INV_READ</>),  writing (<symbol>INV_WRITE</symbol>),  or
179 180
     both.
     A  large  object cannot be opened before it is created.
181 182 183
     <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
184 185
     <function>lo_close</function>.  The descriptor is only valid for
     the duration of the current transaction.
T
Thomas G. Lockhart 已提交
186 187
</para>
</sect2>
188

T
Thomas G. Lockhart 已提交
189 190
<sect2>
<title>Writing Data to a Large Object</title>
191

T
Thomas G. Lockhart 已提交
192
<para>
193 194 195 196
     The function
<synopsis>
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
</synopsis>
197
     writes <parameter>len</parameter> bytes from <parameter>buf</parameter> to large object <parameter>fd</>.   The <parameter>fd</parameter>
198
     argument must have been returned by a previous <function>lo_open</function>.
199 200
     The number of bytes actually written is  returned.   In
     the event of an error, the return value is negative.
T
Thomas G. Lockhart 已提交
201 202
</para>
</sect2>
203

204 205 206 207
<sect2>
<title>Reading Data from a Large Object</title>

<para>
208 209 210 211
     The function
<synopsis>
int lo_read(PGconn *conn, int fd, char *buf, size_t len);
</synopsis>
212
     reads <parameter>len</parameter> bytes from large object <parameter>fd</parameter> into <parameter>buf</parameter>. The  <parameter>fd</parameter>
213 214 215 216 217 218
     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>

T
Thomas G. Lockhart 已提交
219 220
<sect2>
<title>Seeking on a Large Object</title>
221

T
Thomas G. Lockhart 已提交
222
<para>
223 224
     To change the current read or write location on a large
     object, call
225 226 227 228
<synopsis>
int lo_lseek(PGconn *conn, int fd, int offset, int whence);
</synopsis>
     This function moves the current location pointer for the
P
Peter Eisentraut 已提交
229 230
     large object described by <parameter>fd</> to the new location specified 
     by <parameter>offset</>.  The valid values for <parameter>whence</> are
231 232 233 234 235 236 237 238 239 240 241 242 243 244
     <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.
</para>
</sect2>

<sect2>
<title>Obtaining the Seek Position of a Large Object</title>

<para>
     To obtain the current read or write location of a large object,
     call
<synopsis>
int lo_tell(PGconn *conn, int fd);
</synopsis>
     If there is an error, the return value is negative.
T
Thomas G. Lockhart 已提交
245 246
</para>
</sect2>
247

T
Thomas G. Lockhart 已提交
248 249
<sect2>
<title>Closing a Large Object Descriptor</title>
250

T
Thomas G. Lockhart 已提交
251
<para>
252
     A large object may be closed by calling
253 254 255
<synopsis>
int lo_close(PGconn *conn, int fd);
</synopsis>
P
Peter Eisentraut 已提交
256
     where  <parameter>fd</>  is  a  large  object  descriptor returned by
257 258
     <function>lo_open</function>.  On success, <function>lo_close</function>
      returns zero.  On error, the return value is negative.
T
Thomas G. Lockhart 已提交
259
</para>
260 261 262 263 264

<para>
     Any large  object  descriptors that remain open at the end of a
     transaction will be closed automatically.
</para>
265
</sect2>
266 267 268 269 270 271 272

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

    <para>
     To remove a large object from the database, call
<synopsis>
273
int lo_unlink(PGconn *conn, Oid lobjId);
274
</synopsis>
P
Peter Eisentraut 已提交
275
     The <parameter>lobjId</parameter> argument specifies  the  OID  of  the  large
276
     object  to  remove.  In the event of an error, the return value is negative.
277 278 279 280
    </para>
   </sect2>


T
Thomas G. Lockhart 已提交
281
</sect1>
282

283
<sect1 id="lo-funcs">
284
<title>Server-side Functions</title>
285

T
Thomas G. Lockhart 已提交
286
<para>
287 288
     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
T
Thomas G. Lockhart 已提交
289
    in  <acronym>SQL</acronym>
290 291
     commands.
     Here is an example of their use:
T
Thomas G. Lockhart 已提交
292
<programlisting>
293 294 295 296 297 298 299 300
CREATE TABLE image (
    name            text,
    raster          oid
);

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

P
Peter Eisentraut 已提交
301
SELECT lo_export(image.raster, '/tmp/motd') FROM image
302
    WHERE name = 'beautiful image';
T
Thomas G. Lockhart 已提交
303 304
</programlisting>
</para>
305 306 307 308 309 310 311 312

<para>
These functions read and write files in the server's filesystem, 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 filesystem, using the permissions of
the client program.  Their use is not restricted.)
</para>
T
Thomas G. Lockhart 已提交
313
</sect1>
314

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

T
Thomas G. Lockhart 已提交
318
<para>
P
Peter Eisentraut 已提交
319
     <xref linkend="lo-example"> is a sample program which shows how the large object  
320
     interface
321
     in  <application>libpq</>  can  be used.  Parts of the program are 
P
Peter Eisentraut 已提交
322
     commented out but are left in the source for  the  reader's
323
     benefit.  This program can also be found in
P
Peter Eisentraut 已提交
324
     <filename>src/test/examples/testlo.c</filename> in the source distribution.
T
Thomas G. Lockhart 已提交
325
</para>
326

P
Peter Eisentraut 已提交
327
  <example id="lo-example">
328
   <title>Large Objects with <application>libpq</application> Example Program</title>
T
Thomas G. Lockhart 已提交
329
<programlisting>
330
/*--------------------------------------------------------------
331 332 333 334 335 336 337 338 339
 *
 * testlo.c--
 *    test using large objects with libpq
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *--------------------------------------------------------------
 */
#include &lt;stdio.h&gt;
340 341
#include &quot;libpq-fe.h&quot;
#include &quot;libpq/libpq-fs.h&quot;
342 343 344 345

#define BUFSIZE          1024

/*
P
Peter Eisentraut 已提交
346 347
 * importFile
 *    import file &quot;in_filename&quot; into database as large object &quot;lobjOid&quot;
348 349
 *
 */
350 351
Oid
importFile(PGconn *conn, char *filename)
352
{
353 354 355 356 357 358
    Oid         lobjId;
    int         lobj_fd;
    char        buf[BUFSIZE];
    int         nbytes,
                tmp;
    int         fd;
359 360 361 362 363

    /*
     * open the file to be read in
     */
    fd = open(filename, O_RDONLY, 0666);
364 365 366
    if (fd &lt; 0)
    {                           /* error */
        fprintf(stderr, &quot;can't open unix file %s\n&quot;, filename);
367 368 369 370 371
    }

    /*
     * create the large object
     */
372 373 374
    lobjId = lo_creat(conn, INV_READ | INV_WRITE);
    if (lobjId == 0)
        fprintf(stderr, &quot;can't create large object\n&quot;);
375 376

    lobj_fd = lo_open(conn, lobjId, INV_WRITE);
377

378 379 380
    /*
     * read in from the Unix file and write to the inversion file
     */
381 382 383 384 385
    while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0)
    {
        tmp = lo_write(conn, lobj_fd, buf, nbytes);
        if (tmp &lt; nbytes)
            fprintf(stderr, &quot;error while reading large object\n&quot;);
386 387 388 389 390 391 392 393
    }

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

    return lobjId;
}

394 395
void
pickout(PGconn *conn, Oid lobjId, int start, int len)
396
{
397 398 399 400
    int         lobj_fd;
    char       *buf;
    int         nbytes;
    int         nread;
401 402

    lobj_fd = lo_open(conn, lobjId, INV_READ);
403 404 405 406
    if (lobj_fd &lt; 0)
    {
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
                lobjId);
407 408 409
    }

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

    nread = 0;
413 414 415 416 417 418
    while (len - nread &gt; 0)
    {
        nbytes = lo_read(conn, lobj_fd, buf, len - nread);
        buf[nbytes] = ' ';
        fprintf(stderr, &quot;&gt;&gt;&gt; %s&quot;, buf);
        nread += nbytes;
419
    }
420 421
    free(buf);
    fprintf(stderr, &quot;\n&quot;);
422 423 424
    lo_close(conn, lobj_fd);
}

425 426
void
overwrite(PGconn *conn, Oid lobjId, int start, int len)
427
{
428 429 430 431 432
    int         lobj_fd;
    char       *buf;
    int         nbytes;
    int         nwritten;
    int         i;
433 434

    lobj_fd = lo_open(conn, lobjId, INV_READ);
435 436 437 438
    if (lobj_fd &lt; 0)
    {
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
                lobjId);
439 440 441
    }

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

444 445
    for (i = 0; i &lt; len; i++)
        buf[i] = 'X';
446 447 448
    buf[i] = ' ';

    nwritten = 0;
449 450 451 452
    while (len - nwritten &gt; 0)
    {
        nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
        nwritten += nbytes;
453
    }
454 455
    free(buf);
    fprintf(stderr, &quot;\n&quot;);
456 457 458 459
    lo_close(conn, lobj_fd);
}

/*
460
 * exportFile *    export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
461 462
 *
 */
463 464
void
exportFile(PGconn *conn, Oid lobjId, char *filename)
465
{
466 467 468 469 470
    int         lobj_fd;
    char        buf[BUFSIZE];
    int         nbytes,
                tmp;
    int         fd;
471 472

    /*
473
     * create an inversion &quot;object&quot;
474 475
     */
    lobj_fd = lo_open(conn, lobjId, INV_READ);
476 477 478 479
    if (lobj_fd &lt; 0)
    {
        fprintf(stderr, &quot;can't open large object %d\n&quot;,
                lobjId);
480 481 482 483 484
    }

    /*
     * open the file to be written to
     */
485 486 487 488 489
    fd = open(filename, O_CREAT | O_WRONLY, 0666);
    if (fd &lt; 0)
    {                           /* error */
        fprintf(stderr, &quot;can't open unix file %s\n&quot;,
                filename);
490 491 492 493 494
    }

    /*
     * read in from the Unix file and write to the inversion file
     */
495 496 497 498 499 500 501 502
    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0)
    {
        tmp = write(fd, buf, nbytes);
        if (tmp &lt; nbytes)
        {
            fprintf(stderr, &quot;error while writing %s\n&quot;,
                    filename);
        }
503 504 505 506 507 508 509 510 511
    }

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

    return;
}

void
512
exit_nicely(PGconn *conn)
513
{
514 515
    PQfinish(conn);
    exit(1);
516 517 518 519 520
}

int
main(int argc, char **argv)
{
521 522 523 524 525 526 527 528 529 530 531 532
    char       *in_filename,
               *out_filename;
    char       *database;
    Oid         lobjOid;
    PGconn     *conn;
    PGresult   *res;

    if (argc != 4)
    {
        fprintf(stderr, &quot;Usage: %s database_name in_filename out_filename\n&quot;,
                argv[0]);
        exit(1);
533 534 535 536 537 538 539 540 541 542 543 544
    }

    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 */
545 546 547 548 549
    if (PQstatus(conn) == CONNECTION_BAD)
    {
        fprintf(stderr, &quot;Connection to database '%s' failed.\n&quot;, database);
        fprintf(stderr, &quot;%s&quot;, PQerrorMessage(conn));
        exit_nicely(conn);
550 551
    }

552
    res = PQexec(conn, &quot;begin&quot;);
553 554
    PQclear(res);

555
    printf(&quot;importing file %s\n&quot;, in_filename);
556 557 558
/*  lobjOid = importFile(conn, in_filename); */
    lobjOid = lo_import(conn, in_filename);
/*
559
    printf(&quot;as large object %d.\n&quot;, lobjOid);
560

561
    printf(&quot;picking out bytes 1000-2000 of the large object\n&quot;);
562 563
    pickout(conn, lobjOid, 1000, 1000);

564
    printf(&quot;overwriting bytes 1000-2000 of the large object with X's\n&quot;);
565 566 567
    overwrite(conn, lobjOid, 1000, 1000);
*/

568
    printf(&quot;exporting large object to file %s\n&quot;, out_filename);
569
/*    exportFile(conn, lobjOid, out_filename); */
570
    lo_export(conn, lobjOid, out_filename);
571

572
    res = PQexec(conn, &quot;end&quot;);
573 574 575 576
    PQclear(res);
    PQfinish(conn);
    exit(0);
}
T
Thomas G. Lockhart 已提交
577
</programlisting>
P
Peter Eisentraut 已提交
578
</example>
T
Thomas G. Lockhart 已提交
579 580 581 582 583 584

</sect1>
</chapter>

<!-- Keep this comment at the end of the file
Local variables:
585
mode:sgml
T
Thomas G. Lockhart 已提交
586 587 588 589 590 591 592 593 594
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
595
sgml-local-catalogs:("/usr/lib/sgml/catalog")
T
Thomas G. Lockhart 已提交
596 597 598
sgml-local-ecat-files:nil
End:
-->