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);
 }
 

Reply via email to