mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
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).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.3 2004/10/30 23:11:26 tgl Exp $
|
||||
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.4 2005/06/13 02:26:53 tgl Exp $
|
||||
# Functions to be exported by libpq DLLs
|
||||
PQconnectdb 1
|
||||
PQsetdbLogin 2
|
||||
@@ -122,3 +122,4 @@ PQsendPrepare 119
|
||||
PQgetCancel 120
|
||||
PQfreeCancel 121
|
||||
PQcancel 122
|
||||
lo_create 123
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.52 2004/12/31 22:03:50 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.53 2005/06/13 02:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -266,12 +266,11 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
|
||||
/*
|
||||
* lo_creat
|
||||
* create a new large object
|
||||
* the mode is a bitmask describing different attributes of the new object
|
||||
* the mode is ignored (once upon a time it had a use)
|
||||
*
|
||||
* returns the oid of the large object created or
|
||||
* InvalidOid upon failure
|
||||
*/
|
||||
|
||||
Oid
|
||||
lo_creat(PGconn *conn, int mode)
|
||||
{
|
||||
@@ -303,6 +302,53 @@ lo_creat(PGconn *conn, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* lo_create
|
||||
* create a new large object
|
||||
* if lobjId isn't InvalidOid, it specifies the OID to (attempt to) create
|
||||
*
|
||||
* returns the oid of the large object created or
|
||||
* InvalidOid upon failure
|
||||
*/
|
||||
Oid
|
||||
lo_create(PGconn *conn, Oid lobjId)
|
||||
{
|
||||
PQArgBlock argv[1];
|
||||
PGresult *res;
|
||||
int retval;
|
||||
int result_len;
|
||||
|
||||
if (conn->lobjfuncs == NULL)
|
||||
{
|
||||
if (lo_initialize(conn) < 0)
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/* Must check this on-the-fly because it's not there pre-8.1 */
|
||||
if (conn->lobjfuncs->fn_lo_create == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_create\n"));
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
argv[0].isint = 1;
|
||||
argv[0].len = 4;
|
||||
argv[0].u.integer = lobjId;
|
||||
res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
|
||||
&retval, &result_len, 1, argv, 1);
|
||||
if (PQresultStatus(res) == PGRES_COMMAND_OK)
|
||||
{
|
||||
PQclear(res);
|
||||
return (Oid) retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
PQclear(res);
|
||||
return InvalidOid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lo_tell
|
||||
@@ -560,7 +606,8 @@ lo_initialize(PGconn *conn)
|
||||
|
||||
/*
|
||||
* Execute the query to get all the functions at once. In 7.3 and
|
||||
* later we need to be schema-safe.
|
||||
* later we need to be schema-safe. lo_create only exists in 8.1
|
||||
* and up.
|
||||
*/
|
||||
if (conn->sversion >= 70300)
|
||||
query = "select proname, oid from pg_catalog.pg_proc "
|
||||
@@ -568,6 +615,7 @@ lo_initialize(PGconn *conn)
|
||||
"'lo_open', "
|
||||
"'lo_close', "
|
||||
"'lo_creat', "
|
||||
"'lo_create', "
|
||||
"'lo_unlink', "
|
||||
"'lo_lseek', "
|
||||
"'lo_tell', "
|
||||
@@ -615,6 +663,8 @@ lo_initialize(PGconn *conn)
|
||||
lobjfuncs->fn_lo_close = foid;
|
||||
else if (!strcmp(fname, "lo_creat"))
|
||||
lobjfuncs->fn_lo_creat = foid;
|
||||
else if (!strcmp(fname, "lo_create"))
|
||||
lobjfuncs->fn_lo_create = foid;
|
||||
else if (!strcmp(fname, "lo_unlink"))
|
||||
lobjfuncs->fn_lo_unlink = foid;
|
||||
else if (!strcmp(fname, "lo_lseek"))
|
||||
@@ -631,7 +681,7 @@ lo_initialize(PGconn *conn)
|
||||
|
||||
/*
|
||||
* Finally check that we really got all large object interface
|
||||
* functions.
|
||||
* functions --- except lo_create, which may not exist.
|
||||
*/
|
||||
if (lobjfuncs->fn_lo_open == 0)
|
||||
{
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.117 2005/06/09 20:01:16 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.118 2005/06/13 02:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -480,6 +480,7 @@ extern int lo_read(PGconn *conn, int fd, char *buf, size_t len);
|
||||
extern int lo_write(PGconn *conn, int fd, char *buf, size_t len);
|
||||
extern int lo_lseek(PGconn *conn, int fd, int offset, int whence);
|
||||
extern Oid lo_creat(PGconn *conn, int mode);
|
||||
extern Oid lo_create(PGconn *conn, Oid lobjId);
|
||||
extern int lo_tell(PGconn *conn, int fd);
|
||||
extern int lo_unlink(PGconn *conn, Oid lobjId);
|
||||
extern Oid lo_import(PGconn *conn, const char *filename);
|
||||
|
@@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.102 2005/06/12 00:00:21 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.103 2005/06/13 02:26:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -229,6 +229,7 @@ typedef struct pgLobjfuncs
|
||||
Oid fn_lo_open; /* OID of backend function lo_open */
|
||||
Oid fn_lo_close; /* OID of backend function lo_close */
|
||||
Oid fn_lo_creat; /* OID of backend function lo_creat */
|
||||
Oid fn_lo_create; /* OID of backend function lo_create */
|
||||
Oid fn_lo_unlink; /* OID of backend function lo_unlink */
|
||||
Oid fn_lo_lseek; /* OID of backend function lo_lseek */
|
||||
Oid fn_lo_tell; /* OID of backend function lo_tell */
|
||||
|
Reference in New Issue
Block a user