From 1503333f8f6fb5dcfdd4f84a9bfa7929c45aa2cc Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 7 Oct 2012 19:16:28 -0400 Subject: [PATCH] Improve documentation about large-object functions. Copy-editing for previous patch, plus fixing some longstanding markup issues and oversights (like not mentioning that failures will set the PQerrorMessage string). --- doc/src/sgml/config.sgml | 7 +- doc/src/sgml/lobj.sgml | 178 +++++++++++++++++++++++++-------------- 2 files changed, 120 insertions(+), 65 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 74a7ca17b2..8388416430 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -5804,17 +5804,18 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' In PostgreSQL releases prior to 9.0, large objects - did not have access privileges and were, in effect, readable and - writable by all users. Setting this variable to on + did not have access privileges and were, therefore, always readable + and writable by all users. Setting this variable to on disables the new privilege checks, for compatibility with prior releases. The default is off. + Only superusers can change this setting. Setting this variable does not disable all security checks related to large objects — only those for which the default behavior has changed in PostgreSQL 9.0. For example, lo_import() and - lo_export() need superuser privileges independent + lo_export() need superuser privileges regardless of this setting. diff --git a/doc/src/sgml/lobj.sgml b/doc/src/sgml/lobj.sgml index 66467e00f3..ba5674cff3 100644 --- a/doc/src/sgml/lobj.sgml +++ b/doc/src/sgml/lobj.sgml @@ -34,17 +34,26 @@ - All large objects are placed in a single system table called - pg_largeobject. + All large objects are stored in a single system table named pg_largeobject. + Each large object also has an entry in the system table pg_largeobject_metadata. + Large objects can be created, modified, and deleted using a read/write API + that is similar to standard operations on files. + + + PostgreSQL also supports a storage system called - TOAST that automatically stores values + TOAST, + which 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 4 TB in size, whereas TOASTed 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 - TOAST. + most 1 GB. Also, reading and updating portions of a large object can be + done efficiently, while most operations on a TOASTed + field will read or write the whole value as a unit. @@ -65,14 +74,14 @@ and a set of access permissions, which can be managed using and . - For compatibility with prior releases, see - . SELECT privileges are required to read a large object, and - UPDATE privileges are required to write to or + UPDATE privileges are required to write or truncate it. - Only the large object owner (or the database superuser) can unlink, comment - on, or change the owner of a large object. + Only the large object's owner (or a database superuser) can delete, + comment on, or change the owner of a large object. + To adjust this behavior for compatibility with prior releases, see the + run-time parameter. @@ -81,20 +90,31 @@ This section describes the facilities that - PostgreSQL client interface libraries - provide for accessing large objects. All large object - manipulation using these functions must take - place within an SQL transaction block. - The PostgreSQL large object interface is modeled after - the Unix file-system interface, with analogues of - open, read, + PostgreSQL's libpq + client interface library provides for accessing large objects. + The PostgreSQL large object interface is + modeled after the Unix file-system interface, with + analogues of open, read, write, lseek, etc. - Client applications which use the large object interface in - libpq should include the header file + All large object manipulation using these functions + must take place within an SQL transaction block, + since large object file descriptors are only valid for the duration of + a transaction. + + + + If an error occurs while executing any one of these functions, the + function will return an otherwise-impossible value, typically 0 or -1. + A message describing the error is stored in the connection object and + can be retrieved with PQerrorMessage. + + + + Client applications that use these functions should include the header file libpq/libpq-fs.h and link with the libpq library. @@ -103,11 +123,11 @@ Creating a Large Object + lo_creat The function Oid lo_creat(PGconn *conn, int mode); - lo_creat creates a new large object. The return value is the OID that was assigned to the new large object, or InvalidOid (zero) on failure. @@ -129,11 +149,11 @@ inv_oid = lo_creat(conn, INV_READ|INV_WRITE); + lo_create The function Oid lo_create(PGconn *conn, Oid lobjId); - lo_create also creates a new large object. The OID to be assigned can be specified by lobjId; if so, failure occurs if that OID is already in use for some large @@ -162,11 +182,11 @@ inv_oid = lo_create(conn, desired_oid); Importing a Large Object + lo_import To import an operating system file as a large object, call Oid lo_import(PGconn *conn, const char *filename); - lo_import filename specifies the operating system name of the file to be imported as a large object. @@ -178,11 +198,11 @@ Oid lo_import(PGconn *conn, const char *filename); + lo_import_with_oid The function Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); - lo_import_with_oid also imports a new large object. The OID to be assigned can be specified by lobjId; if so, failure occurs if that OID is already in use for some large @@ -204,12 +224,12 @@ Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); Exporting a Large Object + lo_export To export a large object into an operating system file, call int lo_export(PGconn *conn, Oid lobjId, const char *filename); - lo_export The lobjId argument specifies the OID of the large object to export and the filename argument specifies the operating system name of the file. Note that the file is @@ -222,24 +242,23 @@ int lo_export(PGconn *conn, Oid lobjId, const char *filename); Opening an Existing Large Object + lo_open To open an existing large object for reading or writing, call int lo_open(PGconn *conn, Oid lobjId, int mode); - lo_open 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 (INV_WRITE), or both. (These symbolic constants are defined in the header file libpq/libpq-fs.h.) - A large object cannot be opened before it is created. lo_open returns a (non-negative) large object descriptor for later use in lo_read, lo_write, lo_lseek, - lo_lseek64, lo_tell, + lo_lseek64, lo_tell, lo_tell64, lo_truncate, - lo_truncate64, and lo_close. + lo_truncate64, and lo_close. The descriptor is only valid for the duration of the current transaction. On failure, -1 is returned. @@ -274,17 +293,17 @@ inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE); Writing Data to a Large Object + lo_write The function int lo_write(PGconn *conn, int fd, const char *buf, size_t len); - lo_write writes - len bytes from buf + writes len bytes from buf to large object descriptor fd. The fd argument must have been returned by a previous lo_open. The number of bytes actually written is returned. In the event of an error, the return value - is negative. + is -1. @@ -292,17 +311,17 @@ int lo_write(PGconn *conn, int fd, const char *buf, size_t len); Reading Data from a Large Object + lo_read The function int lo_read(PGconn *conn, int fd, char *buf, size_t len); - lo_read reads - len bytes from large object descriptor + reads len bytes from large object descriptor fd into buf. The fd argument must have been returned by a previous lo_open. The number of bytes actually read is returned. In the event of an error, the return - value is negative. + value is -1. @@ -310,13 +329,13 @@ int lo_read(PGconn *conn, int fd, char *buf, size_t len); Seeking in a Large Object + lo_lseek To change the current read or write location associated with a large object descriptor, call int lo_lseek(PGconn *conn, int fd, int offset, int whence); -pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); - lo_lseek This function moves the + This function moves the current location pointer for the large object descriptor identified by fd to the new location specified by offset. The valid values for whence @@ -324,14 +343,27 @@ pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); SEEK_CUR (seek from current position), and SEEK_END (seek from object end). The return value is the new location pointer, or -1 on error. - lo_lseek64 lo_lseek64 - is a function for large objects larger than 2GB. pg_int64 - is defined as 8-byte integer type. + + + lo_lseek64 + When dealing with large objects that might exceed 2GB in size, + instead use + +pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); + + This function has the same behavior + as lo_lseek, but it can accept an + offset larger than 2GB and/or deliver a result larger + than 2GB. + Note that lo_lseek will fail if the new location + pointer would be greater than 2GB. + + lo_lseek64 is new as of PostgreSQL - 9.3; if this function is run against an older server version, it will - fail and return a negative value. + 9.3. If this function is run against an older server version, it will + fail and return -1. @@ -340,21 +372,33 @@ pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); Obtaining the Seek Position of a Large Object + lo_tell To obtain the current read or write location of a large object descriptor, call int lo_tell(PGconn *conn, int fd); + + If there is an error, the return value is -1. + + + + lo_tell64 + When dealing with large objects that might exceed 2GB in size, + instead use + pg_int64 lo_tell64(PGconn *conn, int fd); - lo_tell If there is an error, the - return value is negative. - lo_tell64 lo_tell64 is - a function for large objects larger than 2GB. + This function has the same behavior + as lo_tell, but it can deliver a result larger + than 2GB. + Note that lo_tell will fail if the current + read/write location is greater than 2GB. + lo_tell64 is new as of PostgreSQL - 9.3; if this function is run against an older server version, it will - fail and return a negative value. + 9.3. If this function is run against an older server version, it will + fail and return -1. @@ -362,39 +406,48 @@ pg_int64 lo_tell64(PGconn *conn, int fd); Truncating a Large Object + lo_truncate To truncate a large object to a given length, call int lo_truncate(PGcon *conn, int fd, size_t len); -int lo_truncate64(PGcon *conn, int fd, pg_int64 len); - lo_truncate truncates the large object + This function truncates the large object descriptor fd to length len. The fd argument must have been returned by a previous lo_open. If len is - greater than the current large object length, the large object + greater than the large object's current length, the large object is extended with null bytes ('\0'). - lo_truncate64 lo_truncate64 - is a function for large objects larger than 2GB. + On success, lo_truncate returns + zero. On error, the return value is -1. - The file offset is not changed. + The read/write location associated with the descriptor + fd is not changed. - On success lo_truncate and lo_truncate64 returns - zero. On error, the return value is negative. + lo_truncate64 + When dealing with large objects that might exceed 2GB in size, + instead use + +int lo_truncate64(PGcon *conn, int fd, pg_int64 len); + + This function has the same + behavior as lo_truncate, but it can accept a + len value exceeding 2GB. lo_truncate is new as of PostgreSQL 8.3; if this function is run against an older server version, it will - fail and return a negative value. + fail and return -1. + lo_truncate64 is new as of PostgreSQL 9.3; if this function is run against an older server version, it will - fail and return a negative value. + fail and return -1. @@ -402,14 +455,15 @@ int lo_truncate64(PGcon *conn, int fd, pg_int64 len); Closing a Large Object Descriptor + lo_close A large object descriptor can be closed by calling int lo_close(PGconn *conn, int fd); - lo_close where fd is a + where fd is a large object descriptor returned by lo_open. On success, lo_close returns zero. On - error, the return value is negative. + error, the return value is -1. @@ -422,12 +476,12 @@ int lo_close(PGconn *conn, int fd); Removing a Large Object + lo_unlink To remove a large object from the database, call int lo_unlink(PGconn *conn, Oid lobjId); - lo_unlink The - lobjId argument specifies the OID of the + The lobjId argument specifies the OID of the large object to remove. Returns 1 if successful, -1 on failure.