Re: Making psql error out on output failures - Mailing list pgsql-hackers

From David Zhang
Subject Re: Making psql error out on output failures
Date
Msg-id f915009f-952b-1745-3fcc-e58ed268a881@highgo.ca
Whole thread Raw
In response to Re: Making psql error out on output failures  ("Daniel Verite" <daniel@manitou-mail.org>)
Responses Re: Making psql error out on output failures  ("Daniel Verite" <daniel@manitou-mail.org>)
List pgsql-hackers
On 2020-01-16 5:20 a.m., Daniel Verite wrote:
>     David Zhang wrote:
>
>> If I change the error log message like below, where "%m" is used to pass the
>> value of strerror(errno), "could not write to output file:" is copied from
>> function "WRITE_ERROR_EXIT".
>> -                       pg_log_error("Error printing tuples");
>> +                       pg_log_error("could not write to output file: %m");
>> then the output message is something like below, which, I believe, is more
>> consistent with pg_dump.
> The problem is that errno may not be reliable to tell us what was
> the problem that leads to ferror(fout) being nonzero, since it isn't
> saved at the point of the error and the output code may have called
> many libc functions between the first occurrence of the output error
> and when pg_log_error() is called.
>
> The linux manpage on errno warns specifically about this:
> <quote from "man errno">
> NOTES
>         A common mistake is to do
>
>        if (somecall() == -1) {
>            printf("somecall() failed\n");
>            if (errno == ...) { ... }
>        }
>
>         where errno no longer needs to have the value  it  had  upon  return
> from  somecall()
>         (i.e.,  it  may    have been changed by the printf(3)).  If the value of
> errno should be
>         preserved across a library call, it must be saved:
> </quote>
>
> This other bit from the POSIX spec [1] is relevant:
>
>    "The value of errno shall be defined only after a call to a function
>    for which it is explicitly stated to be set and until it is changed
>    by the next function call or if the application assigns it a value."
>
> To use errno in a way that complies with the above, the psql code
> should be refactored. I don't know if having a more precise error
> message justifies that refactoring. I've elaborated a bit about that
> upthread with the initial submission.

Yes, I agree with you. For case 2 "select repeat('111', 1000000) \g
/mnt/ramdisk/file", it can be easily fixed with more accurate error
message similar to pg_dump, one example could be something like below.
But for case 1 "psql -d postgres  -At -c "select repeat('111', 1000000)"
 > /mnt/ramdisk/file" , it may require a lot of refactoring work.

diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 8fd997553e..e6c239fd9f 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -309,8 +309,10 @@ flushbuffer(PrintfTarget *target)

                 written = fwrite(target->bufstart, 1, nc, target->stream);
                 target->nchars += written;
-               if (written != nc)
+               if (written != nc) {
                         target->failed = true;
+                       fprintf(stderr, "could not write to output file:
%s\n", strerror(errno));
+               }

> Besides, I'm not even
> sure that errno is necessarily set on non-POSIX platforms when fputc
> or fputs fails.
Verified, fputs does set the errno at least in Ubuntu Linux.
> That's why this patch uses the safer approach to emit a generic
> error message.
>
> [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html
>
>
> Best regards,
--
David

Software Engineer
Highgo Software Inc. (Canada)
www.highgo.ca





pgsql-hackers by date:

Previous
From: Dilip Kumar
Date:
Subject: Re: [HACKERS] Block level parallel vacuum
Next
From: Andreas Joseph Krogh
Date:
Subject: Re: Minimal logical decoding on standbys