Skip to content

Commit c92d146

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 cf516dc commit c92d146

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
@@ -136,7 +136,7 @@ typedef struct CopyStateData
136136

137137
/* these are just for error messages, see CopyFromErrorCallback */
138138
const char *cur_relname; /* table name for error messages */
139-
int cur_lineno; /* line number for error messages */
139+
uint64 cur_lineno; /* line number for error messages */
140140
const char *cur_attname; /* current att for error messages */
141141
const char *cur_attval; /* current att value for error messages */
142142

@@ -309,7 +309,7 @@ static void CopyFromInsertBatch(CopyState cstate, EState *estate,
309309
ResultRelInfo *resultRelInfo, TupleTableSlot *myslot,
310310
BulkInsertState bistate,
311311
int nBufferedTuples, HeapTuple *bufferedTuples,
312-
int firstBufferedLineNo);
312+
uint64 firstBufferedLineNo);
313313
static bool CopyReadLine(CopyState cstate);
314314
static bool CopyReadLineText(CopyState cstate);
315315
static int CopyReadAttributesText(CopyState cstate);
@@ -2174,17 +2174,21 @@ void
21742174
CopyFromErrorCallback(void *arg)
21752175
{
21762176
CopyState cstate = (CopyState) arg;
2177+
char curlineno_str[32];
2178+
2179+
snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
2180+
cstate->cur_lineno);
21772181

21782182
if (cstate->binary)
21792183
{
21802184
/* can't usefully display the data */
21812185
if (cstate->cur_attname)
2182-
errcontext("COPY %s, line %d, column %s",
2183-
cstate->cur_relname, cstate->cur_lineno,
2186+
errcontext("COPY %s, line %s, column %s",
2187+
cstate->cur_relname, curlineno_str,
21842188
cstate->cur_attname);
21852189
else
2186-
errcontext("COPY %s, line %d",
2187-
cstate->cur_relname, cstate->cur_lineno);
2190+
errcontext("COPY %s, line %s",
2191+
cstate->cur_relname, curlineno_str);
21882192
}
21892193
else
21902194
{
@@ -2194,16 +2198,16 @@ CopyFromErrorCallback(void *arg)
21942198
char *attval;
21952199

21962200
attval = limit_printout_length(cstate->cur_attval);
2197-
errcontext("COPY %s, line %d, column %s: \"%s\"",
2198-
cstate->cur_relname, cstate->cur_lineno,
2201+
errcontext("COPY %s, line %s, column %s: \"%s\"",
2202+
cstate->cur_relname, curlineno_str,
21992203
cstate->cur_attname, attval);
22002204
pfree(attval);
22012205
}
22022206
else if (cstate->cur_attname)
22032207
{
22042208
/* error is relevant to a particular column, value is NULL */
2205-
errcontext("COPY %s, line %d, column %s: null input",
2206-
cstate->cur_relname, cstate->cur_lineno,
2209+
errcontext("COPY %s, line %s, column %s: null input",
2210+
cstate->cur_relname, curlineno_str,
22072211
cstate->cur_attname);
22082212
}
22092213
else
@@ -2224,14 +2228,14 @@ CopyFromErrorCallback(void *arg)
22242228
char *lineval;
22252229

22262230
lineval = limit_printout_length(cstate->line_buf.data);
2227-
errcontext("COPY %s, line %d: \"%s\"",
2228-
cstate->cur_relname, cstate->cur_lineno, lineval);
2231+
errcontext("COPY %s, line %s: \"%s\"",
2232+
cstate->cur_relname, curlineno_str, lineval);
22292233
pfree(lineval);
22302234
}
22312235
else
22322236
{
2233-
errcontext("COPY %s, line %d",
2234-
cstate->cur_relname, cstate->cur_lineno);
2237+
errcontext("COPY %s, line %s",
2238+
cstate->cur_relname, curlineno_str);
22352239
}
22362240
}
22372241
}
@@ -2301,7 +2305,7 @@ CopyFrom(CopyState cstate)
23012305
#define MAX_BUFFERED_TUPLES 1000
23022306
HeapTuple *bufferedTuples = NULL; /* initialize to silence warning */
23032307
Size bufferedTuplesSize = 0;
2304-
int firstBufferedLineNo = 0;
2308+
uint64 firstBufferedLineNo = 0;
23052309

23062310
Assert(cstate->rel);
23072311

@@ -2902,11 +2906,11 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
29022906
int hi_options, ResultRelInfo *resultRelInfo,
29032907
TupleTableSlot *myslot, BulkInsertState bistate,
29042908
int nBufferedTuples, HeapTuple *bufferedTuples,
2905-
int firstBufferedLineNo)
2909+
uint64 firstBufferedLineNo)
29062910
{
29072911
MemoryContext oldcontext;
29082912
int i;
2909-
int save_cur_lineno;
2913+
uint64 save_cur_lineno;
29102914

29112915
/*
29122916
* Print error context information correctly, if one of the operations

0 commit comments

Comments
 (0)