Commit 7897e3bb authored by Thomas Munro's avatar Thomas Munro

Fix buffile.c error handling.

Convert buffile.c error handling to use ereport.  This fixes cases where
I/O errors were indistinguishable from EOF or not reported.  Also remove
"%m" from error messages where errno would be bogus.  While we're
modifying those strings, add block numbers and short read byte counts
where appropriate.

Back-patch to all supported releases.
Reported-by: default avatarAmit Khandekar <amitdkhan.pg@gmail.com>
Reviewed-by: default avatarMelanie Plageman <melanieplageman@gmail.com>
Reviewed-by: default avatarAlvaro Herrera <alvherre@2ndquadrant.com>
Reviewed-by: default avatarRobert Haas <robertmhaas@gmail.com>
Reviewed-by: default avatarIbrar Ahmed <ibrar.ahmad@gmail.com>
Reviewed-by: default avatarMichael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CA%2BhUKGJE04G%3D8TLK0DLypT_27D9dR8F1RQgNp0jK6qR0tZGWOw%40mail.gmail.com
parent 4c5cf543
...@@ -757,26 +757,20 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, ...@@ -757,26 +757,20 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate,
static void static void
ReadTempFileBlock(BufFile *file, long blknum, void *ptr) ReadTempFileBlock(BufFile *file, long blknum, void *ptr)
{ {
size_t nread;
if (BufFileSeekBlock(file, blknum) != 0) if (BufFileSeekBlock(file, blknum) != 0)
elog(ERROR, "could not seek temporary file: %m"); elog(ERROR, "could not seek to block %ld in temporary file", blknum);
if (BufFileRead(file, ptr, BLCKSZ) != BLCKSZ) nread = BufFileRead(file, ptr, BLCKSZ);
elog(ERROR, "could not read temporary file: %m"); if (nread != BLCKSZ)
elog(ERROR, "could not read temporary file: read only %zu of %zu bytes",
nread, (size_t) BLCKSZ);
} }
static void static void
WriteTempFileBlock(BufFile *file, long blknum, void *ptr) WriteTempFileBlock(BufFile *file, long blknum, void *ptr)
{ {
if (BufFileSeekBlock(file, blknum) != 0) if (BufFileSeekBlock(file, blknum) != 0)
elog(ERROR, "could not seek temporary file: %m"); elog(ERROR, "could not seek to block %ld in temporary file", blknum);
if (BufFileWrite(file, ptr, BLCKSZ) != BLCKSZ) BufFileWrite(file, ptr, BLCKSZ);
{
/*
* the other errors in Read/WriteTempFileBlock shouldn't happen, but
* an error at write can easily happen if you run out of disk space.
*/
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write block %ld of temporary file: %m",
blknum)));
}
} }
...@@ -1043,7 +1043,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate) ...@@ -1043,7 +1043,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
if (BufFileSeek(innerFile, 0, 0L, SEEK_SET)) if (BufFileSeek(innerFile, 0, 0L, SEEK_SET))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not rewind hash-join temporary file: %m"))); errmsg("could not rewind hash-join temporary file")));
while ((slot = ExecHashJoinGetSavedTuple(hjstate, while ((slot = ExecHashJoinGetSavedTuple(hjstate,
innerFile, innerFile,
...@@ -1073,7 +1073,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate) ...@@ -1073,7 +1073,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
if (BufFileSeek(hashtable->outerBatchFile[curbatch], 0, 0L, SEEK_SET)) if (BufFileSeek(hashtable->outerBatchFile[curbatch], 0, 0L, SEEK_SET))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not rewind hash-join temporary file: %m"))); errmsg("could not rewind hash-join temporary file")));
} }
return true; return true;
...@@ -1219,7 +1219,6 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue, ...@@ -1219,7 +1219,6 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
BufFile **fileptr) BufFile **fileptr)
{ {
BufFile *file = *fileptr; BufFile *file = *fileptr;
size_t written;
if (file == NULL) if (file == NULL)
{ {
...@@ -1228,17 +1227,8 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue, ...@@ -1228,17 +1227,8 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
*fileptr = file; *fileptr = file;
} }
written = BufFileWrite(file, (void *) &hashvalue, sizeof(uint32)); BufFileWrite(file, (void *) &hashvalue, sizeof(uint32));
if (written != sizeof(uint32)) BufFileWrite(file, (void *) tuple, tuple->t_len);
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)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to hash-join temporary file: %m")));
} }
/* /*
...@@ -1279,7 +1269,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate, ...@@ -1279,7 +1269,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
if (nread != sizeof(header)) if (nread != sizeof(header))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from hash-join temporary file: %m"))); errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
nread, sizeof(header))));
*hashvalue = header[0]; *hashvalue = header[0];
tuple = (MinimalTuple) palloc(header[1]); tuple = (MinimalTuple) palloc(header[1]);
tuple->t_len = header[1]; tuple->t_len = header[1];
...@@ -1289,7 +1280,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate, ...@@ -1289,7 +1280,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
if (nread != header[1] - sizeof(uint32)) if (nread != header[1] - sizeof(uint32))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from hash-join temporary file: %m"))); errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
nread, header[1] - sizeof(uint32))));
ExecForceStoreMinimalTuple(tuple, tupleSlot, true); ExecForceStoreMinimalTuple(tuple, tupleSlot, true);
return tupleSlot; return tupleSlot;
} }
......
...@@ -319,7 +319,7 @@ SendBackupManifest(backup_manifest_info *manifest) ...@@ -319,7 +319,7 @@ SendBackupManifest(backup_manifest_info *manifest)
if (BufFileSeek(manifest->buffile, 0, 0L, SEEK_SET)) if (BufFileSeek(manifest->buffile, 0, 0L, SEEK_SET))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not rewind temporary file: %m"))); errmsg("could not rewind temporary file")));
/* Send CopyOutResponse message */ /* Send CopyOutResponse message */
pq_beginmessage(&protobuf, 'H'); pq_beginmessage(&protobuf, 'H');
...@@ -365,15 +365,10 @@ static void ...@@ -365,15 +365,10 @@ static void
AppendStringToManifest(backup_manifest_info *manifest, char *s) AppendStringToManifest(backup_manifest_info *manifest, char *s)
{ {
int len = strlen(s); int len = strlen(s);
size_t written;
Assert(manifest != NULL); Assert(manifest != NULL);
if (manifest->still_checksumming) if (manifest->still_checksumming)
pg_sha256_update(&manifest->manifest_ctx, (uint8 *) s, len); pg_sha256_update(&manifest->manifest_ctx, (uint8 *) s, len);
written = BufFileWrite(manifest->buffile, s, len); BufFileWrite(manifest->buffile, s, len);
if (written != len)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to temporary file: %m")));
manifest->manifest_size += len; manifest->manifest_size += len;
} }
...@@ -99,7 +99,7 @@ static BufFile *makeBufFile(File firstfile); ...@@ -99,7 +99,7 @@ static BufFile *makeBufFile(File firstfile);
static void extendBufFile(BufFile *file); static void extendBufFile(BufFile *file);
static void BufFileLoadBuffer(BufFile *file); static void BufFileLoadBuffer(BufFile *file);
static void BufFileDumpBuffer(BufFile *file); static void BufFileDumpBuffer(BufFile *file);
static int BufFileFlush(BufFile *file); static void BufFileFlush(BufFile *file);
static File MakeNewSharedSegment(BufFile *file, int segment); static File MakeNewSharedSegment(BufFile *file, int segment);
/* /*
...@@ -434,7 +434,14 @@ BufFileLoadBuffer(BufFile *file) ...@@ -434,7 +434,14 @@ BufFileLoadBuffer(BufFile *file)
file->curOffset, file->curOffset,
WAIT_EVENT_BUFFILE_READ); WAIT_EVENT_BUFFILE_READ);
if (file->nbytes < 0) if (file->nbytes < 0)
{
file->nbytes = 0; file->nbytes = 0;
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read file \"%s\": %m",
FilePathName(thisfile))));
}
/* we choose not to advance curOffset here */ /* we choose not to advance curOffset here */
if (file->nbytes > 0) if (file->nbytes > 0)
...@@ -490,7 +497,10 @@ BufFileDumpBuffer(BufFile *file) ...@@ -490,7 +497,10 @@ BufFileDumpBuffer(BufFile *file)
file->curOffset, file->curOffset,
WAIT_EVENT_BUFFILE_WRITE); WAIT_EVENT_BUFFILE_WRITE);
if (bytestowrite <= 0) if (bytestowrite <= 0)
return; /* failed to write */ ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to file \"%s\" : %m",
FilePathName(thisfile))));
file->curOffset += bytestowrite; file->curOffset += bytestowrite;
wpos += bytestowrite; wpos += bytestowrite;
...@@ -522,7 +532,8 @@ BufFileDumpBuffer(BufFile *file) ...@@ -522,7 +532,8 @@ BufFileDumpBuffer(BufFile *file)
/* /*
* BufFileRead * BufFileRead
* *
* Like fread() except we assume 1-byte element size. * Like fread() except we assume 1-byte element size and report I/O errors via
* ereport().
*/ */
size_t size_t
BufFileRead(BufFile *file, void *ptr, size_t size) BufFileRead(BufFile *file, void *ptr, size_t size)
...@@ -530,12 +541,7 @@ BufFileRead(BufFile *file, void *ptr, size_t size) ...@@ -530,12 +541,7 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
size_t nread = 0; size_t nread = 0;
size_t nthistime; size_t nthistime;
if (file->dirty) BufFileFlush(file);
{
if (BufFileFlush(file) != 0)
return 0; /* could not flush... */
Assert(!file->dirty);
}
while (size > 0) while (size > 0)
{ {
...@@ -569,7 +575,8 @@ BufFileRead(BufFile *file, void *ptr, size_t size) ...@@ -569,7 +575,8 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
/* /*
* BufFileWrite * BufFileWrite
* *
* Like fwrite() except we assume 1-byte element size. * Like fwrite() except we assume 1-byte element size and report errors via
* ereport().
*/ */
size_t size_t
BufFileWrite(BufFile *file, void *ptr, size_t size) BufFileWrite(BufFile *file, void *ptr, size_t size)
...@@ -585,11 +592,7 @@ BufFileWrite(BufFile *file, void *ptr, size_t size) ...@@ -585,11 +592,7 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
{ {
/* Buffer full, dump it out */ /* Buffer full, dump it out */
if (file->dirty) if (file->dirty)
{
BufFileDumpBuffer(file); BufFileDumpBuffer(file);
if (file->dirty)
break; /* I/O error */
}
else else
{ {
/* Hmm, went directly from reading to writing? */ /* Hmm, went directly from reading to writing? */
...@@ -621,19 +624,15 @@ BufFileWrite(BufFile *file, void *ptr, size_t size) ...@@ -621,19 +624,15 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
/* /*
* BufFileFlush * BufFileFlush
* *
* Like fflush() * Like fflush(), except that I/O errors are reported with ereport().
*/ */
static int static void
BufFileFlush(BufFile *file) BufFileFlush(BufFile *file)
{ {
if (file->dirty) if (file->dirty)
{
BufFileDumpBuffer(file); BufFileDumpBuffer(file);
if (file->dirty)
return EOF;
}
return 0; Assert(!file->dirty);
} }
/* /*
...@@ -642,6 +641,7 @@ BufFileFlush(BufFile *file) ...@@ -642,6 +641,7 @@ BufFileFlush(BufFile *file)
* Like fseek(), except that target position needs two values in order to * Like fseek(), except that target position needs two values in order to
* work when logical filesize exceeds maximum value representable by off_t. * work when logical filesize exceeds maximum value representable by off_t.
* We do not support relative seeks across more than that, however. * We do not support relative seeks across more than that, however.
* I/O errors are reported by ereport().
* *
* Result is 0 if OK, EOF if not. Logical position is not moved if an * Result is 0 if OK, EOF if not. Logical position is not moved if an
* impossible seek is attempted. * impossible seek is attempted.
...@@ -699,8 +699,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence) ...@@ -699,8 +699,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
return 0; return 0;
} }
/* Otherwise, must reposition buffer, so flush any dirty data */ /* Otherwise, must reposition buffer, so flush any dirty data */
if (BufFileFlush(file) != 0) BufFileFlush(file);
return EOF;
/* /*
* At this point and no sooner, check for seek past last segment. The * At this point and no sooner, check for seek past last segment. The
......
...@@ -262,12 +262,12 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) ...@@ -262,12 +262,12 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
} }
/* Write the requested block */ /* Write the requested block */
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 || if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
BufFileWrite(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not write block %ld of temporary file: %m", errmsg("could not seek to block %ld of temporary file",
blocknum))); blocknum)));
BufFileWrite(lts->pfile, buffer, BLCKSZ);
/* Update nBlocksWritten, if we extended the file */ /* Update nBlocksWritten, if we extended the file */
if (blocknum == lts->nBlocksWritten) if (blocknum == lts->nBlocksWritten)
...@@ -283,12 +283,19 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) ...@@ -283,12 +283,19 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
static void static void
ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer) ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
{ {
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 || size_t nread;
BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read block %ld of temporary file: %m", errmsg("could not seek to block %ld of temporary file",
blocknum))); blocknum)));
nread = BufFileRead(lts->pfile, buffer, BLCKSZ);
if (nread != BLCKSZ)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read block %ld of temporary file: read only %zu of %zu bytes",
blocknum, nread, (size_t) BLCKSZ)));
} }
/* /*
......
...@@ -196,14 +196,9 @@ static void ...@@ -196,14 +196,9 @@ static void
sts_flush_chunk(SharedTuplestoreAccessor *accessor) sts_flush_chunk(SharedTuplestoreAccessor *accessor)
{ {
size_t size; size_t size;
size_t written;
size = STS_CHUNK_PAGES * BLCKSZ; size = STS_CHUNK_PAGES * BLCKSZ;
written = BufFileWrite(accessor->write_file, accessor->write_chunk, size); BufFileWrite(accessor->write_file, accessor->write_chunk, size);
if (written != size)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to temporary file: %m")));
memset(accessor->write_chunk, 0, size); memset(accessor->write_chunk, 0, size);
accessor->write_pointer = &accessor->write_chunk->data[0]; accessor->write_pointer = &accessor->write_chunk->data[0];
accessor->sts->participants[accessor->participant].npages += accessor->sts->participants[accessor->participant].npages +=
...@@ -555,6 +550,7 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data) ...@@ -555,6 +550,7 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
if (!eof) if (!eof)
{ {
SharedTuplestoreChunk chunk_header; SharedTuplestoreChunk chunk_header;
size_t nread;
/* Make sure we have the file open. */ /* Make sure we have the file open. */
if (accessor->read_file == NULL) if (accessor->read_file == NULL)
...@@ -570,14 +566,15 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data) ...@@ -570,14 +566,15 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
if (BufFileSeekBlock(accessor->read_file, read_page) != 0) if (BufFileSeekBlock(accessor->read_file, read_page) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from shared tuplestore temporary file"), errmsg("could not seek block %u in shared tuplestore temporary file",
errdetail_internal("Could not seek to next block."))); read_page)));
if (BufFileRead(accessor->read_file, &chunk_header, nread = BufFileRead(accessor->read_file, &chunk_header,
STS_CHUNK_HEADER_SIZE) != STS_CHUNK_HEADER_SIZE) STS_CHUNK_HEADER_SIZE);
if (nread != STS_CHUNK_HEADER_SIZE)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from shared tuplestore temporary file"), errmsg("could not read from shared tuplestore temporary file: read only %zu of %zu bytes",
errdetail_internal("Short read while reading chunk header."))); nread, STS_CHUNK_HEADER_SIZE)));
/* /*
* If this is an overflow chunk, we skip it and any following * If this is an overflow chunk, we skip it and any following
......
...@@ -515,7 +515,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr) ...@@ -515,7 +515,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
} }
else else
{ {
...@@ -525,7 +525,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr) ...@@ -525,7 +525,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
} }
break; break;
default: default:
...@@ -866,7 +866,7 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple) ...@@ -866,7 +866,7 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
state->status = TSS_WRITEFILE; state->status = TSS_WRITEFILE;
/* /*
...@@ -970,7 +970,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward, ...@@ -970,7 +970,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
state->status = TSS_READFILE; state->status = TSS_READFILE;
/* FALLTHROUGH */ /* FALLTHROUGH */
...@@ -1034,7 +1034,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward, ...@@ -1034,7 +1034,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
SEEK_CUR) != 0) SEEK_CUR) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
Assert(!state->truncated); Assert(!state->truncated);
return NULL; return NULL;
} }
...@@ -1051,7 +1051,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward, ...@@ -1051,7 +1051,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
SEEK_CUR) != 0) SEEK_CUR) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
tup = READTUP(state, tuplen); tup = READTUP(state, tuplen);
return tup; return tup;
...@@ -1253,7 +1253,7 @@ tuplestore_rescan(Tuplestorestate *state) ...@@ -1253,7 +1253,7 @@ tuplestore_rescan(Tuplestorestate *state)
if (BufFileSeek(state->myfile, 0, 0L, SEEK_SET) != 0) if (BufFileSeek(state->myfile, 0, 0L, SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
break; break;
default: default:
elog(ERROR, "invalid tuplestore state"); elog(ERROR, "invalid tuplestore state");
...@@ -1318,7 +1318,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state, ...@@ -1318,7 +1318,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
} }
else else
{ {
...@@ -1327,7 +1327,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state, ...@@ -1327,7 +1327,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
SEEK_SET) != 0) SEEK_SET) != 0)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not seek in tuplestore temporary file: %m"))); errmsg("could not seek in tuplestore temporary file")));
} }
} }
else if (srcptr == state->activeptr) else if (srcptr == state->activeptr)
...@@ -1474,7 +1474,8 @@ getlen(Tuplestorestate *state, bool eofOK) ...@@ -1474,7 +1474,8 @@ getlen(Tuplestorestate *state, bool eofOK)
if (nbytes != 0 || !eofOK) if (nbytes != 0 || !eofOK)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from tuplestore temporary file: %m"))); errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
nbytes, sizeof(len))));
return 0; return 0;
} }
...@@ -1511,22 +1512,10 @@ writetup_heap(Tuplestorestate *state, void *tup) ...@@ -1511,22 +1512,10 @@ writetup_heap(Tuplestorestate *state, void *tup)
/* total on-disk footprint: */ /* total on-disk footprint: */
unsigned int tuplen = tupbodylen + sizeof(int); unsigned int tuplen = tupbodylen + sizeof(int);
if (BufFileWrite(state->myfile, (void *) &tuplen, BufFileWrite(state->myfile, (void *) &tuplen, sizeof(tuplen));
sizeof(tuplen)) != sizeof(tuplen)) BufFileWrite(state->myfile, (void *) tupbody, tupbodylen);
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to tuplestore temporary file: %m")));
if (BufFileWrite(state->myfile, (void *) tupbody,
tupbodylen) != (size_t) tupbodylen)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to tuplestore temporary file: %m")));
if (state->backward) /* need trailing length word? */ if (state->backward) /* need trailing length word? */
if (BufFileWrite(state->myfile, (void *) &tuplen, BufFileWrite(state->myfile, (void *) &tuplen, sizeof(tuplen));
sizeof(tuplen)) != sizeof(tuplen))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to tuplestore temporary file: %m")));
FREEMEM(state, GetMemoryChunkSpace(tuple)); FREEMEM(state, GetMemoryChunkSpace(tuple));
heap_free_minimal_tuple(tuple); heap_free_minimal_tuple(tuple);
...@@ -1539,20 +1528,25 @@ readtup_heap(Tuplestorestate *state, unsigned int len) ...@@ -1539,20 +1528,25 @@ readtup_heap(Tuplestorestate *state, unsigned int len)
unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET; unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
MinimalTuple tuple = (MinimalTuple) palloc(tuplen); MinimalTuple tuple = (MinimalTuple) palloc(tuplen);
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET; char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
size_t nread;
USEMEM(state, GetMemoryChunkSpace(tuple)); USEMEM(state, GetMemoryChunkSpace(tuple));
/* read in the tuple proper */ /* read in the tuple proper */
tuple->t_len = tuplen; tuple->t_len = tuplen;
if (BufFileRead(state->myfile, (void *) tupbody, nread = BufFileRead(state->myfile, (void *) tupbody, tupbodylen);
tupbodylen) != (size_t) tupbodylen) if (nread != (size_t) tupbodylen)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from tuplestore temporary file: %m"))); errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
nread, (size_t) tupbodylen)));
if (state->backward) /* need trailing length word? */ if (state->backward) /* need trailing length word? */
if (BufFileRead(state->myfile, (void *) &tuplen, {
sizeof(tuplen)) != sizeof(tuplen)) nread = BufFileRead(state->myfile, (void *) &tuplen, sizeof(tuplen));
if (nread != sizeof(tuplen))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read from tuplestore temporary file: %m"))); errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
nread, sizeof(tuplen))));
}
return (void *) tuple; return (void *) tuple;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment