mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Fix lo_import and lo_export to return useful error messages more often.
I found that these functions tend to return -1 while leaving an empty error message string in the PGconn, if they suffer some kind of I/O error on the file. The reason is that lo_close, which thinks it's executed a perfectly fine SQL command, clears the errorMessage. The minimum-change workaround is to reorder operations here so that we don't fill the errorMessage until after lo_close.
This commit is contained in:
@ -168,7 +168,7 @@ lo_truncate(PGconn *conn, int fd, size_t len)
|
|||||||
if (len > (size_t) INT_MAX)
|
if (len > (size_t) INT_MAX)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("argument of lo_truncate exceeds integer range\n"));
|
libpq_gettext("argument of lo_truncate exceeds integer range\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ lo_truncate64(PGconn *conn, int fd, pg_int64 len)
|
|||||||
if (conn->lobjfuncs->fn_lo_truncate64 == 0)
|
if (conn->lobjfuncs->fn_lo_truncate64 == 0)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("cannot determine OID of function lo_truncate64\n"));
|
libpq_gettext("cannot determine OID of function lo_truncate64\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
|
|||||||
if (len > (size_t) INT_MAX)
|
if (len > (size_t) INT_MAX)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("argument of lo_read exceeds integer range\n"));
|
libpq_gettext("argument of lo_read exceeds integer range\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +332,7 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
|
|||||||
if (len > (size_t) INT_MAX)
|
if (len > (size_t) INT_MAX)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("argument of lo_write exceeds integer range\n"));
|
libpq_gettext("argument of lo_write exceeds integer range\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +423,7 @@ lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
|
|||||||
if (conn->lobjfuncs->fn_lo_lseek64 == 0)
|
if (conn->lobjfuncs->fn_lo_lseek64 == 0)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("cannot determine OID of function lo_lseek64\n"));
|
libpq_gettext("cannot determine OID of function lo_lseek64\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +598,7 @@ lo_tell64(PGconn *conn, int fd)
|
|||||||
if (conn->lobjfuncs->fn_lo_tell64 == 0)
|
if (conn->lobjfuncs->fn_lo_tell64 == 0)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("cannot determine OID of function lo_tell64\n"));
|
libpq_gettext("cannot determine OID of function lo_tell64\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,10 +753,16 @@ lo_import_internal(PGconn *conn, const char *filename, Oid oid)
|
|||||||
|
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
|
/* We must do lo_close before setting the errorMessage */
|
||||||
|
int save_errno = errno;
|
||||||
|
|
||||||
|
(void) lo_close(conn, lobj);
|
||||||
|
(void) close(fd);
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not read from file \"%s\": %s\n"),
|
libpq_gettext("could not read from file \"%s\": %s\n"),
|
||||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
filename,
|
||||||
lobjOid = InvalidOid;
|
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
|
||||||
|
return InvalidOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
@ -801,11 +807,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
|||||||
*/
|
*/
|
||||||
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
|
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{ /* error */
|
{
|
||||||
|
/* We must do lo_close before setting the errorMessage */
|
||||||
|
int save_errno = errno;
|
||||||
|
|
||||||
|
(void) lo_close(conn, lobj);
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not open file \"%s\": %s\n"),
|
libpq_gettext("could not open file \"%s\": %s\n"),
|
||||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
filename,
|
||||||
(void) lo_close(conn, lobj);
|
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,11 +827,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
|||||||
tmp = write(fd, buf, nbytes);
|
tmp = write(fd, buf, nbytes);
|
||||||
if (tmp != nbytes)
|
if (tmp != nbytes)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
/* We must do lo_close before setting the errorMessage */
|
||||||
libpq_gettext("could not write to file \"%s\": %s\n"),
|
int save_errno = errno;
|
||||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
|
||||||
(void) lo_close(conn, lobj);
|
(void) lo_close(conn, lobj);
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("could not write to file \"%s\": %s\n"),
|
||||||
|
filename,
|
||||||
|
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -839,7 +853,8 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
|||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(fd))
|
/* if we already failed, don't overwrite that msg with a close error */
|
||||||
|
if (close(fd) && result >= 0)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not write to file \"%s\": %s\n"),
|
libpq_gettext("could not write to file \"%s\": %s\n"),
|
||||||
|
Reference in New Issue
Block a user