From: | David Zhang <david(dot)zhang(at)highgo(dot)ca> |
---|---|
To: | Daniel Verite <daniel(at)manitou-mail(dot)org> |
Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
Subject: | Re: Making psql error out on output failures |
Date: | 2020-01-17 07:23:43 |
Message-ID: | f915009f-952b-1745-3fcc-e58ed268a881@highgo.ca |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | Andreas Joseph Krogh | 2020-01-17 07:49:49 | Re: Minimal logical decoding on standbys |
Previous Message | Dilip Kumar | 2020-01-17 07:20:46 | Re: [HACKERS] Block level parallel vacuum |