mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Simplify SortTocFromFile() by removing fixed buffer-size limit.
pg_restore previously coped with overlength TOC-file lines using some complicated logic to ignore additional bufferloads. While this isn't wrong, since we don't expect that the interesting part of a line would run to more than a dozen or so bytes, it's more complex than it needs to be. Use a StringInfo instead of a fixed-size buffer so that we can process long lines as single entities and thus not need the extra logic. Daniel Gustafsson Discussion: https://postgr.es/m/48A4FA71-524E-41B9-953A-FD04EF36E2E7@yesql.se
This commit is contained in:
parent
c0cb87fbb6
commit
2e3c19462d
@ -30,8 +30,10 @@
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "common/string.h"
|
||||
#include "dumputils.h"
|
||||
#include "fe_utils/string_utils.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "libpq/libpq-fs.h"
|
||||
#include "parallel.h"
|
||||
#include "pg_backup_archiver.h"
|
||||
@ -1367,8 +1369,7 @@ SortTocFromFile(Archive *AHX)
|
||||
ArchiveHandle *AH = (ArchiveHandle *) AHX;
|
||||
RestoreOptions *ropt = AH->public.ropt;
|
||||
FILE *fh;
|
||||
char buf[100];
|
||||
bool incomplete_line;
|
||||
StringInfoData linebuf;
|
||||
|
||||
/* Allocate space for the 'wanted' array, and init it */
|
||||
ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId);
|
||||
@ -1378,45 +1379,33 @@ SortTocFromFile(Archive *AHX)
|
||||
if (!fh)
|
||||
fatal("could not open TOC file \"%s\": %m", ropt->tocFile);
|
||||
|
||||
incomplete_line = false;
|
||||
while (fgets(buf, sizeof(buf), fh) != NULL)
|
||||
initStringInfo(&linebuf);
|
||||
|
||||
while (pg_get_line_buf(fh, &linebuf))
|
||||
{
|
||||
bool prev_incomplete_line = incomplete_line;
|
||||
int buflen;
|
||||
char *cmnt;
|
||||
char *endptr;
|
||||
DumpId id;
|
||||
TocEntry *te;
|
||||
|
||||
/*
|
||||
* Some lines in the file might be longer than sizeof(buf). This is
|
||||
* no problem, since we only care about the leading numeric ID which
|
||||
* can be at most a few characters; but we have to skip continuation
|
||||
* bufferloads when processing a long line.
|
||||
*/
|
||||
buflen = strlen(buf);
|
||||
if (buflen > 0 && buf[buflen - 1] == '\n')
|
||||
incomplete_line = false;
|
||||
else
|
||||
incomplete_line = true;
|
||||
if (prev_incomplete_line)
|
||||
continue;
|
||||
|
||||
/* Truncate line at comment, if any */
|
||||
cmnt = strchr(buf, ';');
|
||||
cmnt = strchr(linebuf.data, ';');
|
||||
if (cmnt != NULL)
|
||||
{
|
||||
cmnt[0] = '\0';
|
||||
linebuf.len = cmnt - linebuf.data;
|
||||
}
|
||||
|
||||
/* Ignore if all blank */
|
||||
if (strspn(buf, " \t\r\n") == strlen(buf))
|
||||
if (strspn(linebuf.data, " \t\r\n") == linebuf.len)
|
||||
continue;
|
||||
|
||||
/* Get an ID, check it's valid and not already seen */
|
||||
id = strtol(buf, &endptr, 10);
|
||||
if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
|
||||
id = strtol(linebuf.data, &endptr, 10);
|
||||
if (endptr == linebuf.data || id <= 0 || id > AH->maxDumpId ||
|
||||
ropt->idWanted[id - 1])
|
||||
{
|
||||
pg_log_warning("line ignored: %s", buf);
|
||||
pg_log_warning("line ignored: %s", linebuf.data);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1443,6 +1432,8 @@ SortTocFromFile(Archive *AHX)
|
||||
_moveBefore(AH->toc, te);
|
||||
}
|
||||
|
||||
pg_free(linebuf.data);
|
||||
|
||||
if (fclose(fh) != 0)
|
||||
fatal("could not close TOC file: %m");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user