]> granicus.if.org Git - postgresql/commitdiff
Widen COPY FROM's current-line-number counter from 32 to 64 bits.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 May 2018 17:32:52 +0000 (13:32 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 May 2018 17:32:52 +0000 (13:32 -0400)
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

src/backend/commands/copy.c

index 770c75fe2cae4c36a2fe9ee102c1e2d45f241647..0a1706c0d135a906fc10cd1fc42a157122d96be8 100644 (file)
@@ -139,7 +139,7 @@ typedef struct CopyStateData
 
        /* these are just for error messages, see CopyFromErrorCallback */
        const char *cur_relname;        /* table name for error messages */
-       int                     cur_lineno;             /* line number for error messages */
+       uint64          cur_lineno;             /* line number for error messages */
        const char *cur_attname;        /* current att for error messages */
        const char *cur_attval;         /* current att value for error messages */
 
@@ -308,7 +308,7 @@ static void CopyFromInsertBatch(CopyState cstate, EState *estate,
                                        ResultRelInfo *resultRelInfo, TupleTableSlot *myslot,
                                        BulkInsertState bistate,
                                        int nBufferedTuples, HeapTuple *bufferedTuples,
-                                       int firstBufferedLineNo);
+                                       uint64 firstBufferedLineNo);
 static bool CopyReadLine(CopyState cstate);
 static bool CopyReadLineText(CopyState cstate);
 static int     CopyReadAttributesText(CopyState cstate);
@@ -2192,17 +2192,21 @@ void
 CopyFromErrorCallback(void *arg)
 {
        CopyState       cstate = (CopyState) arg;
+       char            curlineno_str[32];
+
+       snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
+                        cstate->cur_lineno);
 
        if (cstate->binary)
        {
                /* can't usefully display the data */
                if (cstate->cur_attname)
-                       errcontext("COPY %s, line %d, column %s",
-                                          cstate->cur_relname, cstate->cur_lineno,
+                       errcontext("COPY %s, line %s, column %s",
+                                          cstate->cur_relname, curlineno_str,
                                           cstate->cur_attname);
                else
-                       errcontext("COPY %s, line %d",
-                                          cstate->cur_relname, cstate->cur_lineno);
+                       errcontext("COPY %s, line %s",
+                                          cstate->cur_relname, curlineno_str);
        }
        else
        {
@@ -2212,16 +2216,16 @@ CopyFromErrorCallback(void *arg)
                        char       *attval;
 
                        attval = limit_printout_length(cstate->cur_attval);
-                       errcontext("COPY %s, line %d, column %s: \"%s\"",
-                                          cstate->cur_relname, cstate->cur_lineno,
+                       errcontext("COPY %s, line %s, column %s: \"%s\"",
+                                          cstate->cur_relname, curlineno_str,
                                           cstate->cur_attname, attval);
                        pfree(attval);
                }
                else if (cstate->cur_attname)
                {
                        /* error is relevant to a particular column, value is NULL */
-                       errcontext("COPY %s, line %d, column %s: null input",
-                                          cstate->cur_relname, cstate->cur_lineno,
+                       errcontext("COPY %s, line %s, column %s: null input",
+                                          cstate->cur_relname, curlineno_str,
                                           cstate->cur_attname);
                }
                else
@@ -2242,14 +2246,14 @@ CopyFromErrorCallback(void *arg)
                                char       *lineval;
 
                                lineval = limit_printout_length(cstate->line_buf.data);
-                               errcontext("COPY %s, line %d: \"%s\"",
-                                                  cstate->cur_relname, cstate->cur_lineno, lineval);
+                               errcontext("COPY %s, line %s: \"%s\"",
+                                                  cstate->cur_relname, curlineno_str, lineval);
                                pfree(lineval);
                        }
                        else
                        {
-                               errcontext("COPY %s, line %d",
-                                                  cstate->cur_relname, cstate->cur_lineno);
+                               errcontext("COPY %s, line %s",
+                                                  cstate->cur_relname, curlineno_str);
                        }
                }
        }
@@ -2320,7 +2324,7 @@ CopyFrom(CopyState cstate)
 #define MAX_BUFFERED_TUPLES 1000
        HeapTuple  *bufferedTuples = NULL;      /* initialize to silence warning */
        Size            bufferedTuplesSize = 0;
-       int                     firstBufferedLineNo = 0;
+       uint64          firstBufferedLineNo = 0;
 
        Assert(cstate->rel);
 
@@ -2903,11 +2907,11 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
                                        int hi_options, ResultRelInfo *resultRelInfo,
                                        TupleTableSlot *myslot, BulkInsertState bistate,
                                        int nBufferedTuples, HeapTuple *bufferedTuples,
-                                       int firstBufferedLineNo)
+                                       uint64 firstBufferedLineNo)
 {
        MemoryContext oldcontext;
        int                     i;
-       int                     save_cur_lineno;
+       uint64          save_cur_lineno;
 
        /*
         * Print error context information correctly, if one of the operations