Hi Tom, thanks for looking.
On 2020-May-25, Tom Lane wrote:
> I don't mind if you want to extend that paradigm to also use "wrote only
> %d bytes" wording, but the important point is to get the SQLSTATE set on
> the basis of ENOSPC rather than whatever random value errno will have
> otherwise.
Hmm, right -- I was extending the partial read case to apply to a
partial write, and we deal with those very differently. I changed the
write case to use our standard approach.
--
Álvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index d13efc4d98..3817c41225 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -882,16 +882,26 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
}
written = BufFileWrite(file, (void *) &hashvalue, sizeof(uint32));
- if (written != sizeof(uint32))
+ if (written < 0)
+ {
+ /* if write didn't set errno, assume problem is no disk space */
+ if (errno == 0)
+ errno = ENOSPC;
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to hash-join temporary file: %m")));
+ }
written = BufFileWrite(file, (void *) tuple, tuple->t_len);
- if (written != tuple->t_len)
+ if (written < 0)
+ {
+ /* if write didn't set errno, assume problem is no disk space */
+ if (errno == 0)
+ errno = ENOSPC;
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to hash-join temporary file: %m")));
+ }
}
/*
@@ -929,20 +939,30 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
ExecClearTuple(tupleSlot);
return NULL;
}
- if (nread != sizeof(header))
+ else if (nread < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read from hash-join temporary file: %m")));
+ else if (nread != sizeof(header))
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read from hash-join temporary file: read only %d of %d bytes",
+ (int) nread, (int) sizeof(header))));
*hashvalue = header[0];
tuple = (MinimalTuple) palloc(header[1]);
tuple->t_len = header[1];
nread = BufFileRead(file,
(void *) ((char *) tuple + sizeof(uint32)),
header[1] - sizeof(uint32));
- if (nread != header[1] - sizeof(uint32))
+ if (nread < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read from hash-join temporary file: %m")));
+ else if (nread != header[1] - sizeof(uint32)) /* might read zero bytes */
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read from hash-join temporary file: read only %d of %d bytes",
+ (int) nread, (int) (header[1] - sizeof(uint32)))));
return ExecStoreMinimalTuple(tuple, tupleSlot, true);
}