Skip to content

Commit ecac235

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 17f188c commit ecac235

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

src/backend/commands/copy.c

+21-17
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ typedef struct CopyStateData
139139

140140
/* these are just for error messages, see CopyFromErrorCallback */
141141
const char *cur_relname; /* table name for error messages */
142-
int cur_lineno; /* line number for error messages */
142+
uint64 cur_lineno; /* line number for error messages */
143143
const char *cur_attname; /* current att for error messages */
144144
const char *cur_attval; /* current att value for error messages */
145145

@@ -308,7 +308,7 @@ static void CopyFromInsertBatch(CopyState cstate, EState *estate,
308308
ResultRelInfo *resultRelInfo, TupleTableSlot *myslot,
309309
BulkInsertState bistate,
310310
int nBufferedTuples, HeapTuple *bufferedTuples,
311-
int firstBufferedLineNo);
311+
uint64 firstBufferedLineNo);
312312
static bool CopyReadLine(CopyState cstate);
313313
static bool CopyReadLineText(CopyState cstate);
314314
static int CopyReadAttributesText(CopyState cstate);
@@ -2192,17 +2192,21 @@ void
21922192
CopyFromErrorCallback(void *arg)
21932193
{
21942194
CopyState cstate = (CopyState) arg;
2195+
char curlineno_str[32];
2196+
2197+
snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
2198+
cstate->cur_lineno);
21952199

21962200
if (cstate->binary)
21972201
{
21982202
/* can't usefully display the data */
21992203
if (cstate->cur_attname)
2200-
errcontext("COPY %s, line %d, column %s",
2201-
cstate->cur_relname, cstate->cur_lineno,
2204+
errcontext("COPY %s, line %s, column %s",
2205+
cstate->cur_relname, curlineno_str,
22022206
cstate->cur_attname);
22032207
else
2204-
errcontext("COPY %s, line %d",
2205-
cstate->cur_relname, cstate->cur_lineno);
2208+
errcontext("COPY %s, line %s",
2209+
cstate->cur_relname, curlineno_str);
22062210
}
22072211
else
22082212
{
@@ -2212,16 +2216,16 @@ CopyFromErrorCallback(void *arg)
22122216
char *attval;
22132217

22142218
attval = limit_printout_length(cstate->cur_attval);
2215-
errcontext("COPY %s, line %d, column %s: \"%s\"",
2216-
cstate->cur_relname, cstate->cur_lineno,
2219+
errcontext("COPY %s, line %s, column %s: \"%s\"",
2220+
cstate->cur_relname, curlineno_str,
22172221
cstate->cur_attname, attval);
22182222
pfree(attval);
22192223
}
22202224
else if (cstate->cur_attname)
22212225
{
22222226
/* error is relevant to a particular column, value is NULL */
2223-
errcontext("COPY %s, line %d, column %s: null input",
2224-
cstate->cur_relname, cstate->cur_lineno,
2227+
errcontext("COPY %s, line %s, column %s: null input",
2228+
cstate->cur_relname, curlineno_str,
22252229
cstate->cur_attname);
22262230
}
22272231
else
@@ -2242,14 +2246,14 @@ CopyFromErrorCallback(void *arg)
22422246
char *lineval;
22432247

22442248
lineval = limit_printout_length(cstate->line_buf.data);
2245-
errcontext("COPY %s, line %d: \"%s\"",
2246-
cstate->cur_relname, cstate->cur_lineno, lineval);
2249+
errcontext("COPY %s, line %s: \"%s\"",
2250+
cstate->cur_relname, curlineno_str, lineval);
22472251
pfree(lineval);
22482252
}
22492253
else
22502254
{
2251-
errcontext("COPY %s, line %d",
2252-
cstate->cur_relname, cstate->cur_lineno);
2255+
errcontext("COPY %s, line %s",
2256+
cstate->cur_relname, curlineno_str);
22532257
}
22542258
}
22552259
}
@@ -2320,7 +2324,7 @@ CopyFrom(CopyState cstate)
23202324
#define MAX_BUFFERED_TUPLES 1000
23212325
HeapTuple *bufferedTuples = NULL; /* initialize to silence warning */
23222326
Size bufferedTuplesSize = 0;
2323-
int firstBufferedLineNo = 0;
2327+
uint64 firstBufferedLineNo = 0;
23242328

23252329
Assert(cstate->rel);
23262330

@@ -2903,11 +2907,11 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
29032907
int hi_options, ResultRelInfo *resultRelInfo,
29042908
TupleTableSlot *myslot, BulkInsertState bistate,
29052909
int nBufferedTuples, HeapTuple *bufferedTuples,
2906-
int firstBufferedLineNo)
2910+
uint64 firstBufferedLineNo)
29072911
{
29082912
MemoryContext oldcontext;
29092913
int i;
2910-
int save_cur_lineno;
2914+
uint64 save_cur_lineno;
29112915

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

0 commit comments

Comments
 (0)