Skip to content

Commit d25714d

Browse files
committed
Widen COPY FROM's current-line-number counter from 32 to 64 bits.
Because the code for the HEADER option skips a line when this counter is zero, a very long COPY FROM WITH HEADER operation would drop a line every 2^32 lines. A lesser but still unfortunate problem is that errors would show a wrong input line number for errors occurring beyond the 2^31'st input line. While such large input streams seemed impractical when this code was first written, they're not any more. Widening the counter (and some associated variables) to uint64 should be enough to prevent problems for the foreseeable future. David Rowley Discussion: https://postgr.es/m/CAKJS1f88yh-6wwEfO6QLEEvH3BEugOq2QX1TOja0vCauoynmOQ@mail.gmail.com
1 parent 769e6fc commit d25714d

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

src/backend/commands/copy.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ typedef struct CopyStateData
133133

134134
/* these are just for error messages, see CopyFromErrorCallback */
135135
const char *cur_relname; /* table name for error messages */
136-
int cur_lineno; /* line number for error messages */
136+
uint64 cur_lineno; /* line number for error messages */
137137
const char *cur_attname; /* current att for error messages */
138138
const char *cur_attval; /* current att value for error messages */
139139

@@ -297,7 +297,7 @@ static void CopyFromInsertBatch(CopyState cstate, EState *estate,
297297
ResultRelInfo *resultRelInfo, TupleTableSlot *myslot,
298298
BulkInsertState bistate,
299299
int nBufferedTuples, HeapTuple *bufferedTuples,
300-
int firstBufferedLineNo);
300+
uint64 firstBufferedLineNo);
301301
static bool CopyReadLine(CopyState cstate);
302302
static bool CopyReadLineText(CopyState cstate);
303303
static int CopyReadAttributesText(CopyState cstate);
@@ -1960,17 +1960,21 @@ void
19601960
CopyFromErrorCallback(void *arg)
19611961
{
19621962
CopyState cstate = (CopyState) arg;
1963+
char curlineno_str[32];
1964+
1965+
snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
1966+
cstate->cur_lineno);
19631967

19641968
if (cstate->binary)
19651969
{
19661970
/* can't usefully display the data */
19671971
if (cstate->cur_attname)
1968-
errcontext("COPY %s, line %d, column %s",
1969-
cstate->cur_relname, cstate->cur_lineno,
1972+
errcontext("COPY %s, line %s, column %s",
1973+
cstate->cur_relname, curlineno_str,
19701974
cstate->cur_attname);
19711975
else
1972-
errcontext("COPY %s, line %d",
1973-
cstate->cur_relname, cstate->cur_lineno);
1976+
errcontext("COPY %s, line %s",
1977+
cstate->cur_relname, curlineno_str);
19741978
}
19751979
else
19761980
{
@@ -1980,16 +1984,16 @@ CopyFromErrorCallback(void *arg)
19801984
char *attval;
19811985

19821986
attval = limit_printout_length(cstate->cur_attval);
1983-
errcontext("COPY %s, line %d, column %s: \"%s\"",
1984-
cstate->cur_relname, cstate->cur_lineno,
1987+
errcontext("COPY %s, line %s, column %s: \"%s\"",
1988+
cstate->cur_relname, curlineno_str,
19851989
cstate->cur_attname, attval);
19861990
pfree(attval);
19871991
}
19881992
else if (cstate->cur_attname)
19891993
{
19901994
/* error is relevant to a particular column, value is NULL */
1991-
errcontext("COPY %s, line %d, column %s: null input",
1992-
cstate->cur_relname, cstate->cur_lineno,
1995+
errcontext("COPY %s, line %s, column %s: null input",
1996+
cstate->cur_relname, curlineno_str,
19931997
cstate->cur_attname);
19941998
}
19951999
else
@@ -2010,14 +2014,14 @@ CopyFromErrorCallback(void *arg)
20102014
char *lineval;
20112015

20122016
lineval = limit_printout_length(cstate->line_buf.data);
2013-
errcontext("COPY %s, line %d: \"%s\"",
2014-
cstate->cur_relname, cstate->cur_lineno, lineval);
2017+
errcontext("COPY %s, line %s: \"%s\"",
2018+
cstate->cur_relname, curlineno_str, lineval);
20152019
pfree(lineval);
20162020
}
20172021
else
20182022
{
2019-
errcontext("COPY %s, line %d",
2020-
cstate->cur_relname, cstate->cur_lineno);
2023+
errcontext("COPY %s, line %s",
2024+
cstate->cur_relname, curlineno_str);
20212025
}
20222026
}
20232027
}
@@ -2085,7 +2089,7 @@ CopyFrom(CopyState cstate)
20852089
#define MAX_BUFFERED_TUPLES 1000
20862090
HeapTuple *bufferedTuples = NULL; /* initialize to silence warning */
20872091
Size bufferedTuplesSize = 0;
2088-
int firstBufferedLineNo = 0;
2092+
uint64 firstBufferedLineNo = 0;
20892093

20902094
Assert(cstate->rel);
20912095

@@ -2440,11 +2444,11 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
24402444
int hi_options, ResultRelInfo *resultRelInfo,
24412445
TupleTableSlot *myslot, BulkInsertState bistate,
24422446
int nBufferedTuples, HeapTuple *bufferedTuples,
2443-
int firstBufferedLineNo)
2447+
uint64 firstBufferedLineNo)
24442448
{
24452449
MemoryContext oldcontext;
24462450
int i;
2447-
int save_cur_lineno;
2451+
uint64 save_cur_lineno;
24482452

24492453
/*
24502454
* Print error context information correctly, if one of the operations

0 commit comments

Comments
 (0)