source: proto/CSV/postgres/copy.c @ 384

Last change on this file since 384 was 384, checked in by lindanl, 9 years ago

Direct bit stream generation; Parallel prefix quote mask.

File size: 112.1 KB
Line 
1/*-------------------------------------------------------------------------
2 *
3 * copy.c
4 *              Implements the COPY utility command
5 *
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 *        $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.312 2009/06/11 14:48:55 momjian Exp $
12 *
13 *-------------------------------------------------------------------------
14 */
15 
16//#define BITSTREAM
17#define BUFFER_PROFILING
18
19#ifdef BUFFER_PROFILING
20#include "Profiling/BOM_Profiler.c"
21BOM_Table * copyloadrawbuf_timer;
22BOM_Table * bitstreamgen_timer;
23BOM_Table * readline_timer;
24BOM_Table * readattr_timer;
25BOM_Table * userattr_timer;
26BOM_Table * tupleattr_timer;
27BOM_Table * loop_timer;
28BOM_Table * copy_timer;
29
30#endif
31
32#include "postgres.h"
33#include <ctype.h>
34#include <unistd.h>
35#include <sys/stat.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38
39#include "access/heapam.h"
40#include "access/xact.h"
41#include "catalog/namespace.h"
42#include "catalog/pg_type.h"
43#include "commands/copy.h"
44#include "commands/trigger.h"
45#include "executor/executor.h"
46#include "libpq/libpq.h"
47#include "libpq/pqformat.h"
48#include "mb/pg_wchar.h"
49#include "miscadmin.h"
50#include "optimizer/planner.h"
51#include "parser/parse_relation.h"
52#include "rewrite/rewriteHandler.h"
53#include "storage/fd.h"
54#include "tcop/tcopprot.h"
55#include "utils/acl.h"
56#include "utils/builtins.h"
57#include "utils/lsyscache.h"
58#include "utils/memutils.h"
59#include "utils/snapmgr.h"
60
61#include "simd_lib/lib_simd.h"
62
63#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
64#define OCTVALUE(c) ((c) - '0')
65
66/*
67 * Represents the different source/dest cases we need to worry about at
68 * the bottom level
69 */
70typedef enum CopyDest
71{
72        COPY_FILE,                                      /* to/from file */
73        COPY_OLD_FE,                            /* to/from frontend (2.0 protocol) */
74        COPY_NEW_FE                                     /* to/from frontend (3.0 protocol) */
75} CopyDest;
76
77/*
78 *      Represents the end-of-line terminator type of the input
79 */
80typedef enum EolType
81{
82        EOL_UNKNOWN,
83        EOL_NL,
84        EOL_CR,
85        EOL_CRNL
86} EolType;
87
88/*
89 * This struct contains all the state variables used throughout a COPY
90 * operation. For simplicity, we use the same struct for all variants of COPY,
91 * even though some fields are used in only some cases.
92 *
93 * Multi-byte encodings: all supported client-side encodings encode multi-byte
94 * characters by having the first byte's high bit set. Subsequent bytes of the
95 * character can have the high bit not set. When scanning data in such an
96 * encoding to look for a match to a single-byte (ie ASCII) character, we must
97 * use the full pg_encoding_mblen() machinery to skip over multibyte
98 * characters, else we might find a false match to a trailing byte. In
99 * supported server encodings, there is no possibility of a false match, and
100 * it's faster to make useless comparisons to trailing bytes than it is to
101 * invoke pg_encoding_mblen() to skip over them. encoding_embeds_ascii is TRUE
102 * when we have to do it the hard way.
103 */
104typedef struct CopyStateData
105{
106        /* low-level state data */
107        CopyDest        copy_dest;              /* type of copy source/destination */
108        FILE       *copy_file;          /* used if copy_dest == COPY_FILE */
109        StringInfo      fe_msgbuf;              /* used for all dests during COPY TO, only for
110                                                                 * dest == COPY_NEW_FE in COPY FROM */
111        bool            fe_copy;                /* true for all FE copy dests */
112        bool            fe_eof;                 /* true if detected end of copy data */
113        EolType         eol_type;               /* EOL type of input */
114        int                     client_encoding;        /* remote side's character encoding */
115        bool            need_transcoding;               /* client encoding diff from server? */
116        bool            encoding_embeds_ascii;  /* ASCII can be non-first byte? */
117        uint64          processed;              /* # of tuples processed */
118
119        /* parameters from the COPY command */
120        Relation        rel;                    /* relation to copy to or from */
121        QueryDesc  *queryDesc;          /* executable query to copy from */
122        List       *attnumlist;         /* integer list of attnums to copy */
123        char       *filename;           /* filename, or NULL for STDIN/STDOUT */
124        bool            binary;                 /* binary format? */
125        bool            oids;                   /* include OIDs? */
126        bool            csv_mode;               /* Comma Separated Value format? */
127        bool            header_line;    /* CSV header line? */
128        char       *null_print;         /* NULL marker string (server encoding!) */
129        int                     null_print_len; /* length of same */
130        char       *null_print_client;          /* same converted to client encoding */
131        char       *delim;                      /* column delimiter (must be 1 byte) */
132        char       *quote;                      /* CSV quote char (must be 1 byte) */
133        char       *escape;                     /* CSV escape char (must be 1 byte) */
134        bool       *force_quote_flags;          /* per-column CSV FQ flags */
135        bool       *force_notnull_flags;        /* per-column CSV FNN flags */
136       
137        /*Bit streams*/
138        SIMD_type * escape_stream;
139        SIMD_type * quote_stream;
140        SIMD_type * delim_stream;
141        SIMD_type * EOL_stream; 
142
143        /* these are just for error messages, see copy_in_error_callback */
144        const char *cur_relname;        /* table name for error messages */
145        int                     cur_lineno;             /* line number for error messages */
146        const char *cur_attname;        /* current att for error messages */
147        const char *cur_attval;         /* current att value for error messages */
148
149        /*
150         * Working state for COPY TO
151         */
152        FmgrInfo   *out_functions;      /* lookup info for output functions */
153        MemoryContext rowcontext;       /* per-row evaluation context */
154
155        /*
156         * These variables are used to reduce overhead in textual COPY FROM.
157         *
158         * attribute_buf holds the separated, de-escaped text for each field of
159         * the current line.  The CopyReadAttributes functions return arrays of
160         * pointers into this buffer.  We avoid palloc/pfree overhead by re-using
161         * the buffer on each cycle.
162         */
163        StringInfoData attribute_buf;
164
165        /*
166         * Similarly, line_buf holds the whole input line being processed. The
167         * input cycle is first to read the whole line into line_buf, convert it
168         * to server encoding there, and then extract the individual attribute
169         * fields into attribute_buf.  line_buf is preserved unmodified so that we
170         * can display it in error messages if appropriate.
171         */
172        StringInfoData line_buf;
173        bool            line_buf_converted;             /* converted to server encoding? */
174
175        /*
176         * Finally, raw_buf holds raw data read from the data source (file or
177         * client connection).  CopyReadLine parses this data sufficiently to
178         * locate line boundaries, then transfers the data to line_buf and
179         * converts it.  Note: we guarantee that there is a \0 at
180         * raw_buf[raw_buf_len].
181         */
182        #define RAW_BUF_SIZE 65536              /* we palloc RAW_BUF_SIZE+1 bytes */
183        char       *raw_buf;
184        int                     raw_buf_index;  /* next byte to process */
185        int                     raw_buf_len;    /* total # of bytes stored */
186} CopyStateData;
187
188typedef CopyStateData *CopyState;
189
190/* DestReceiver for COPY (SELECT) TO */
191typedef struct
192{
193        DestReceiver pub;                       /* publicly-known function pointers */
194        CopyState       cstate;                 /* CopyStateData for the command */
195} DR_copy;
196
197
198
199
200const int BLOCK_SIZE_BYTES = sizeof(SIMD_type);
201const int BLOCK_SIZE_BITS = sizeof(SIMD_type)*8;
202
203#include "copy_simd.c"
204
205
206/*
207 * These macros centralize code used to process line_buf and raw_buf buffers.
208 * They are macros because they often do continue/break control and to avoid
209 * function call overhead in tight COPY loops.
210 *
211 * We must use "if (1)" because the usual "do {...} while(0)" wrapper would
212 * prevent the continue/break processing from working.  We end the "if (1)"
213 * with "else ((void) 0)" to ensure the "if" does not unintentionally match
214 * any "else" in the calling code, and to avoid any compiler warnings about
215 * empty statements.  See http://www.cit.gu.edu.au/~anthony/info/C/C.macros.
216 */
217
218/*
219 * This keeps the character read at the top of the loop in the buffer
220 * even if there is more than one read-ahead.
221 */
222#define IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(extralen) \
223if (1) \
224{ \
225        if (raw_buf_ptr + (extralen) >= copy_buf_len && !hit_eof) \
226        { \
227                raw_buf_ptr = prev_raw_ptr; /* undo fetch */ \
228                need_data = true; \
229                continue; \
230        } \
231} else ((void) 0)
232
233/* This consumes the remainder of the buffer and breaks */
234#define IF_NEED_REFILL_AND_EOF_BREAK(extralen) \
235if (1) \
236{ \
237        if (raw_buf_ptr + (extralen) >= copy_buf_len && hit_eof) \
238        { \
239                if (extralen) \
240                        raw_buf_ptr = copy_buf_len; /* consume the partial character */ \
241                /* backslash just before EOF, treat as data char */ \
242                result = true; \
243                break; \
244        } \
245} else ((void) 0)
246
247/*
248 * Transfer any approved data to line_buf; must do this to be sure
249 * there is some room in raw_buf.
250 */
251#define REFILL_LINEBUF \
252if (1) \
253{ \
254        if (raw_buf_ptr > cstate->raw_buf_index) \
255        { \
256                appendBinaryStringInfo(&cstate->line_buf, \
257                                                         cstate->raw_buf + cstate->raw_buf_index, \
258                                                           raw_buf_ptr - cstate->raw_buf_index); \
259                cstate->raw_buf_index = raw_buf_ptr; \
260        } \
261} else ((void) 0)
262
263/* Undo any read-ahead and jump out of the block. */
264#define NO_END_OF_COPY_GOTO \
265if (1) \
266{ \
267        raw_buf_ptr = prev_raw_ptr + 1; \
268        goto not_end_of_copy; \
269} else ((void) 0)
270
271static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
272
273
274/* non-export function prototypes */
275static void DoCopyTo(CopyState cstate);
276static void CopyTo(CopyState cstate);
277static void CopyOneRowTo(CopyState cstate, Oid tupleOid,
278                         Datum *values, bool *nulls);
279static void CopyFrom(CopyState cstate);
280static bool CopyReadLine(CopyState cstate);
281static bool CopyReadLineText(CopyState cstate);
282static int CopyReadAttributesText(CopyState cstate, int maxfields,
283                                           char **fieldvals);
284static int CopyReadAttributesCSV(CopyState cstate, int maxfields,
285                                          char **fieldvals);
286static Datum CopyReadBinaryAttribute(CopyState cstate,
287                                                int column_no, FmgrInfo *flinfo,
288                                                Oid typioparam, int32 typmod,
289                                                bool *isnull);
290static void CopyAttributeOutText(CopyState cstate, char *string);
291static void CopyAttributeOutCSV(CopyState cstate, char *string,
292                                        bool use_quote, bool single_attr);
293static List *CopyGetAttnums(TupleDesc tupDesc, Relation rel,
294                           List *attnamelist);
295static char *limit_printout_length(const char *str);
296
297/* Low-level communications functions */
298static void SendCopyBegin(CopyState cstate);
299static void ReceiveCopyBegin(CopyState cstate);
300static void SendCopyEnd(CopyState cstate);
301static void CopySendData(CopyState cstate, void *databuf, int datasize);
302static void CopySendString(CopyState cstate, const char *str);
303static void CopySendChar(CopyState cstate, char c);
304static void CopySendEndOfRow(CopyState cstate);
305static int CopyGetData(CopyState cstate, void *databuf,
306                        int minread, int maxread);
307static void CopySendInt32(CopyState cstate, int32 val);
308static bool CopyGetInt32(CopyState cstate, int32 *val);
309static void CopySendInt16(CopyState cstate, int16 val);
310static bool CopyGetInt16(CopyState cstate, int16 *val);
311
312/*
313 * Send copy start/stop messages for frontend copies.  These have changed
314 * in past protocol redesigns.
315 */
316static void
317SendCopyBegin(CopyState cstate)
318{
319        if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
320        {
321                /* new way */
322                StringInfoData buf;
323                int                     natts = list_length(cstate->attnumlist);
324                int16           format = (cstate->binary ? 1 : 0);
325                int                     i;
326
327                pq_beginmessage(&buf, 'H');
328                pq_sendbyte(&buf, format);              /* overall format */
329                pq_sendint(&buf, natts, 2);
330                for (i = 0; i < natts; i++)
331                        pq_sendint(&buf, format, 2);            /* per-column formats */
332                pq_endmessage(&buf);
333                cstate->copy_dest = COPY_NEW_FE;
334        }
335        else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
336        {
337                /* old way */
338                if (cstate->binary)
339                        ereport(ERROR,
340                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
341                        errmsg("COPY BINARY is not supported to stdout or from stdin")));
342                pq_putemptymessage('H');
343                /* grottiness needed for old COPY OUT protocol */
344                pq_startcopyout();
345                cstate->copy_dest = COPY_OLD_FE;
346        }
347        else
348        {
349                /* very old way */
350                if (cstate->binary)
351                        ereport(ERROR,
352                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
353                        errmsg("COPY BINARY is not supported to stdout or from stdin")));
354                pq_putemptymessage('B');
355                /* grottiness needed for old COPY OUT protocol */
356                pq_startcopyout();
357                cstate->copy_dest = COPY_OLD_FE;
358        }
359}
360
361static void
362ReceiveCopyBegin(CopyState cstate)
363{
364        if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
365        {
366                /* new way */
367                StringInfoData buf;
368                int                     natts = list_length(cstate->attnumlist);
369                int16           format = (cstate->binary ? 1 : 0);
370                int                     i;
371
372                pq_beginmessage(&buf, 'G');
373                pq_sendbyte(&buf, format);              /* overall format */
374                pq_sendint(&buf, natts, 2);
375                for (i = 0; i < natts; i++)
376                        pq_sendint(&buf, format, 2);            /* per-column formats */
377                pq_endmessage(&buf);
378                cstate->copy_dest = COPY_NEW_FE;
379                cstate->fe_msgbuf = makeStringInfo();
380        }
381        else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
382        {
383                /* old way */
384                if (cstate->binary)
385                        ereport(ERROR,
386                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
387                        errmsg("COPY BINARY is not supported to stdout or from stdin")));
388                pq_putemptymessage('G');
389                cstate->copy_dest = COPY_OLD_FE;
390        }
391        else
392        {
393                /* very old way */
394                if (cstate->binary)
395                        ereport(ERROR,
396                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
397                        errmsg("COPY BINARY is not supported to stdout or from stdin")));
398                pq_putemptymessage('D');
399                cstate->copy_dest = COPY_OLD_FE;
400        }
401        /* We *must* flush here to ensure FE knows it can send. */
402        pq_flush();
403}
404
405static void
406SendCopyEnd(CopyState cstate)
407{
408        if (cstate->copy_dest == COPY_NEW_FE)
409        {
410                /* Shouldn't have any unsent data */
411                Assert(cstate->fe_msgbuf->len == 0);
412                /* Send Copy Done message */
413                pq_putemptymessage('c');
414        }
415        else
416        {
417                CopySendData(cstate, "\\.", 2);
418                /* Need to flush out the trailer (this also appends a newline) */
419                CopySendEndOfRow(cstate);
420                pq_endcopyout(false);
421        }
422}
423
424/*----------
425 * CopySendData sends output data to the destination (file or frontend)
426 * CopySendString does the same for null-terminated strings
427 * CopySendChar does the same for single characters
428 * CopySendEndOfRow does the appropriate thing at end of each data row
429 *      (data is not actually flushed except by CopySendEndOfRow)
430 *
431 * NB: no data conversion is applied by these functions
432 *----------
433 */
434static void
435CopySendData(CopyState cstate, void *databuf, int datasize)
436{
437        appendBinaryStringInfo(cstate->fe_msgbuf, (char *) databuf, datasize);
438}
439
440static void
441CopySendString(CopyState cstate, const char *str)
442{
443        appendBinaryStringInfo(cstate->fe_msgbuf, str, strlen(str));
444}
445
446static void
447CopySendChar(CopyState cstate, char c)
448{
449        appendStringInfoCharMacro(cstate->fe_msgbuf, c);
450}
451
452static void
453CopySendEndOfRow(CopyState cstate)
454{
455        StringInfo      fe_msgbuf = cstate->fe_msgbuf;
456
457        switch (cstate->copy_dest)
458        {
459                case COPY_FILE:
460                        if (!cstate->binary)
461                        {
462                                /* Default line termination depends on platform */
463#ifndef WIN32
464                                CopySendChar(cstate, '\n');
465#else
466                                CopySendString(cstate, "\r\n");
467#endif
468                        }
469
470                        (void) fwrite(fe_msgbuf->data, fe_msgbuf->len,
471                                                  1, cstate->copy_file);
472                        if (ferror(cstate->copy_file))
473                                ereport(ERROR,
474                                                (errcode_for_file_access(),
475                                                 errmsg("could not write to COPY file: %m")));
476                        break;
477                case COPY_OLD_FE:
478                        /* The FE/BE protocol uses \n as newline for all platforms */
479                        if (!cstate->binary)
480                                CopySendChar(cstate, '\n');
481
482                        if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len))
483                        {
484                                /* no hope of recovering connection sync, so FATAL */
485                                ereport(FATAL,
486                                                (errcode(ERRCODE_CONNECTION_FAILURE),
487                                                 errmsg("connection lost during COPY to stdout")));
488                        }
489                        break;
490                case COPY_NEW_FE:
491                        /* The FE/BE protocol uses \n as newline for all platforms */
492                        if (!cstate->binary)
493                                CopySendChar(cstate, '\n');
494
495                        /* Dump the accumulated row as one CopyData message */
496                        (void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len);
497                        break;
498        }
499
500        resetStringInfo(fe_msgbuf);
501}
502
503/*
504 * CopyGetData reads data from the source (file or frontend)
505 *
506 * We attempt to read at least minread, and at most maxread, bytes from
507 * the source.  The actual number of bytes read is returned; if this is
508 * less than minread, EOF was detected.
509 *
510 * Note: when copying from the frontend, we expect a proper EOF mark per
511 * protocol; if the frontend simply drops the connection, we raise error.
512 * It seems unwise to allow the COPY IN to complete normally in that case.
513 *
514 * NB: no data conversion is applied here.
515 */
516static int
517CopyGetData(CopyState cstate, void *databuf, int minread, int maxread)
518{
519        int                     bytesread = 0;
520
521        switch (cstate->copy_dest)
522        {
523                case COPY_FILE:
524                        bytesread = fread(databuf, 1, maxread, cstate->copy_file);
525                        if (ferror(cstate->copy_file))
526                                ereport(ERROR,
527                                                (errcode_for_file_access(),
528                                                 errmsg("could not read from COPY file: %m")));
529                        break;
530                case COPY_OLD_FE:
531
532                        /*
533                         * We cannot read more than minread bytes (which in practice is 1)
534                         * because old protocol doesn't have any clear way of separating
535                         * the COPY stream from following data.  This is slow, but not any
536                         * slower than the code path was originally, and we don't care
537                         * much anymore about the performance of old protocol.
538                         */
539                        if (pq_getbytes((char *) databuf, minread))
540                        {
541                                /* Only a \. terminator is legal EOF in old protocol */
542                                ereport(ERROR,
543                                                (errcode(ERRCODE_CONNECTION_FAILURE),
544                                                 errmsg("unexpected EOF on client connection")));
545                        }
546                        bytesread = minread;
547                        break;
548                case COPY_NEW_FE:
549                        while (maxread > 0 && bytesread < minread && !cstate->fe_eof)
550                        {
551                                int                     avail;
552
553                                while (cstate->fe_msgbuf->cursor >= cstate->fe_msgbuf->len)
554                                {
555                                        /* Try to receive another message */
556                                        int                     mtype;
557
558                        readmessage:
559                                        mtype = pq_getbyte();
560                                        if (mtype == EOF)
561                                                ereport(ERROR,
562                                                                (errcode(ERRCODE_CONNECTION_FAILURE),
563                                                         errmsg("unexpected EOF on client connection")));
564                                        if (pq_getmessage(cstate->fe_msgbuf, 0))
565                                                ereport(ERROR,
566                                                                (errcode(ERRCODE_CONNECTION_FAILURE),
567                                                         errmsg("unexpected EOF on client connection")));
568                                        switch (mtype)
569                                        {
570                                                case 'd':               /* CopyData */
571                                                        break;
572                                                case 'c':               /* CopyDone */
573                                                        /* COPY IN correctly terminated by frontend */
574                                                        cstate->fe_eof = true;
575                                                        return bytesread;
576                                                case 'f':               /* CopyFail */
577                                                        ereport(ERROR,
578                                                                        (errcode(ERRCODE_QUERY_CANCELED),
579                                                                         errmsg("COPY from stdin failed: %s",
580                                                                           pq_getmsgstring(cstate->fe_msgbuf))));
581                                                        break;
582                                                case 'H':               /* Flush */
583                                                case 'S':               /* Sync */
584
585                                                        /*
586                                                         * Ignore Flush/Sync for the convenience of client
587                                                         * libraries (such as libpq) that may send those
588                                                         * without noticing that the command they just
589                                                         * sent was COPY.
590                                                         */
591                                                        goto readmessage;
592                                                default:
593                                                        ereport(ERROR,
594                                                                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
595                                                                         errmsg("unexpected message type 0x%02X during COPY from stdin",
596                                                                                        mtype)));
597                                                        break;
598                                        }
599                                }
600                                avail = cstate->fe_msgbuf->len - cstate->fe_msgbuf->cursor;
601                                if (avail > maxread)
602                                        avail = maxread;
603                                pq_copymsgbytes(cstate->fe_msgbuf, databuf, avail);
604                                databuf = (void *) ((char *) databuf + avail);
605                                maxread -= avail;
606                                bytesread += avail;
607                        }
608                        break;
609        }
610
611        return bytesread;
612}
613
614
615/*
616 * These functions do apply some data conversion
617 */
618
619/*
620 * CopySendInt32 sends an int32 in network byte order
621 */
622static void
623CopySendInt32(CopyState cstate, int32 val)
624{
625        uint32          buf;
626
627        buf = htonl((uint32) val);
628        CopySendData(cstate, &buf, sizeof(buf));
629}
630
631/*
632 * CopyGetInt32 reads an int32 that appears in network byte order
633 *
634 * Returns true if OK, false if EOF
635 */
636static bool
637CopyGetInt32(CopyState cstate, int32 *val)
638{
639        uint32          buf;
640
641        if (CopyGetData(cstate, &buf, sizeof(buf), sizeof(buf)) != sizeof(buf))
642        {
643                *val = 0;                               /* suppress compiler warning */
644                return false;
645        }
646        *val = (int32) ntohl(buf);
647        return true;
648}
649
650/*
651 * CopySendInt16 sends an int16 in network byte order
652 */
653static void
654CopySendInt16(CopyState cstate, int16 val)
655{
656        uint16          buf;
657
658        buf = htons((uint16) val);
659        CopySendData(cstate, &buf, sizeof(buf));
660}
661
662/*
663 * CopyGetInt16 reads an int16 that appears in network byte order
664 */
665static bool
666CopyGetInt16(CopyState cstate, int16 *val)
667{
668        uint16          buf;
669
670        if (CopyGetData(cstate, &buf, sizeof(buf), sizeof(buf)) != sizeof(buf))
671        {
672                *val = 0;                               /* suppress compiler warning */
673                return false;
674        }
675        *val = (int16) ntohs(buf);
676        return true;
677}
678
679
680/*
681 * CopyLoadRawBuf loads some more data into raw_buf
682 *
683 * Returns TRUE if able to obtain at least one more byte, else FALSE.
684 *
685 * If raw_buf_index < raw_buf_len, the unprocessed bytes are transferred
686 * down to the start of the buffer and then we load more data after that.
687 * This case is used only when a frontend multibyte character crosses a
688 * bufferload boundary.
689 */
690static bool
691CopyLoadRawBuf(CopyState cstate)
692{
693        int                     nbytes;
694        int                     inbytes;
695
696        if (cstate->raw_buf_index < cstate->raw_buf_len)
697        {
698                /* Copy down the unprocessed data */
699                nbytes = cstate->raw_buf_len - cstate->raw_buf_index;
700                memmove(cstate->raw_buf, cstate->raw_buf + cstate->raw_buf_index,
701                                nbytes);
702        }
703        else
704                nbytes = 0;                             /* no data need be saved */
705
706        inbytes = CopyGetData(cstate, cstate->raw_buf + nbytes,
707                                                  1, RAW_BUF_SIZE - nbytes);
708        nbytes += inbytes;
709        cstate->raw_buf[nbytes] = '\0';
710        cstate->raw_buf_index = 0;
711        cstate->raw_buf_len = nbytes;
712//      bitstream_gen(cstate);
713                       
714        return (inbytes > 0);
715}
716
717/*
718 *       DoCopy executes the SQL COPY statement
719 *
720 * Either unload or reload contents of table <relation>, depending on <from>.
721 * (<from> = TRUE means we are inserting into the table.)  In the "TO" case
722 * we also support copying the output of an arbitrary SELECT query.
723 *
724 * If <pipe> is false, transfer is between the table and the file named
725 * <filename>.  Otherwise, transfer is between the table and our regular
726 * input/output stream. The latter could be either stdin/stdout or a
727 * socket, depending on whether we're running under Postmaster control.
728 *
729 * Iff <binary>, unload or reload in the binary format, as opposed to the
730 * more wasteful but more robust and portable text format.
731 *
732 * Iff <oids>, unload or reload the format that includes OID information.
733 * On input, we accept OIDs whether or not the table has an OID column,
734 * but silently drop them if it does not.  On output, we report an error
735 * if the user asks for OIDs in a table that has none (not providing an
736 * OID column might seem friendlier, but could seriously confuse programs).
737 *
738 * If in the text format, delimit columns with delimiter <delim> and print
739 * NULL values as <null_print>.
740 *
741 * Do not allow a Postgres user without superuser privilege to read from
742 * or write to a file.
743 *
744 * Do not allow the copy if user doesn't have proper permission to access
745 * the table or the specifically requested columns.
746 */
747uint64
748DoCopy(const CopyStmt *stmt, const char *queryString)
749{
750        CopyState       cstate;
751        bool            is_from = stmt->is_from;
752        bool            pipe = (stmt->filename == NULL);
753        List       *attnamelist = stmt->attlist;
754        List       *force_quote = NIL;
755        List       *force_notnull = NIL;
756        AclMode         required_access = (is_from ? ACL_INSERT : ACL_SELECT);
757        AclMode         relPerms;
758        AclMode         remainingPerms;
759        ListCell   *option;
760        TupleDesc       tupDesc;
761        int                     num_phys_attrs;
762        uint64          processed;
763
764        /* Allocate workspace and zero all fields */
765        cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
766
767        /* Extract options from the statement node tree */
768        foreach(option, stmt->options)
769        {
770                DefElem    *defel = (DefElem *) lfirst(option);
771
772                if (strcmp(defel->defname, "binary") == 0)
773                {
774                        if (cstate->binary)
775                                ereport(ERROR,
776                                                (errcode(ERRCODE_SYNTAX_ERROR),
777                                                 errmsg("conflicting or redundant options")));
778                        cstate->binary = intVal(defel->arg);
779                }
780                else if (strcmp(defel->defname, "oids") == 0)
781                {
782                        if (cstate->oids)
783                                ereport(ERROR,
784                                                (errcode(ERRCODE_SYNTAX_ERROR),
785                                                 errmsg("conflicting or redundant options")));
786                        cstate->oids = intVal(defel->arg);
787                }
788                else if (strcmp(defel->defname, "delimiter") == 0)
789                {
790                        if (cstate->delim)
791                                ereport(ERROR,
792                                                (errcode(ERRCODE_SYNTAX_ERROR),
793                                                 errmsg("conflicting or redundant options")));
794                        cstate->delim = strVal(defel->arg);
795                }
796                else if (strcmp(defel->defname, "null") == 0)
797                {
798                        if (cstate->null_print)
799                                ereport(ERROR,
800                                                (errcode(ERRCODE_SYNTAX_ERROR),
801                                                 errmsg("conflicting or redundant options")));
802                        cstate->null_print = strVal(defel->arg);
803                }
804                else if (strcmp(defel->defname, "csv") == 0)
805                {
806                        if (cstate->csv_mode)
807                                ereport(ERROR,
808                                                (errcode(ERRCODE_SYNTAX_ERROR),
809                                                 errmsg("conflicting or redundant options")));
810                        cstate->csv_mode = intVal(defel->arg);
811                }
812                else if (strcmp(defel->defname, "header") == 0)
813                {
814                        if (cstate->header_line)
815                                ereport(ERROR,
816                                                (errcode(ERRCODE_SYNTAX_ERROR),
817                                                 errmsg("conflicting or redundant options")));
818                        cstate->header_line = intVal(defel->arg);
819                }
820                else if (strcmp(defel->defname, "quote") == 0)
821                {
822                        if (cstate->quote)
823                                ereport(ERROR,
824                                                (errcode(ERRCODE_SYNTAX_ERROR),
825                                                 errmsg("conflicting or redundant options")));
826                        cstate->quote = strVal(defel->arg);
827                }
828                else if (strcmp(defel->defname, "escape") == 0)
829                {
830                        if (cstate->escape)
831                                ereport(ERROR,
832                                                (errcode(ERRCODE_SYNTAX_ERROR),
833                                                 errmsg("conflicting or redundant options")));
834                        cstate->escape = strVal(defel->arg);
835                }
836                else if (strcmp(defel->defname, "force_quote") == 0)
837                {
838                        if (force_quote)
839                                ereport(ERROR,
840                                                (errcode(ERRCODE_SYNTAX_ERROR),
841                                                 errmsg("conflicting or redundant options")));
842                        force_quote = (List *) defel->arg;
843                }
844                else if (strcmp(defel->defname, "force_notnull") == 0)
845                {
846                        if (force_notnull)
847                                ereport(ERROR,
848                                                (errcode(ERRCODE_SYNTAX_ERROR),
849                                                 errmsg("conflicting or redundant options")));
850                        force_notnull = (List *) defel->arg;
851                }
852                else
853                        elog(ERROR, "option \"%s\" not recognized",
854                                 defel->defname);
855        }
856
857        /* Check for incompatible options */
858        if (cstate->binary && cstate->delim)
859                ereport(ERROR,
860                                (errcode(ERRCODE_SYNTAX_ERROR),
861                                 errmsg("cannot specify DELIMITER in BINARY mode")));
862
863        if (cstate->binary && cstate->csv_mode)
864                ereport(ERROR,
865                                (errcode(ERRCODE_SYNTAX_ERROR),
866                                 errmsg("cannot specify CSV in BINARY mode")));
867
868        if (cstate->binary && cstate->null_print)
869                ereport(ERROR,
870                                (errcode(ERRCODE_SYNTAX_ERROR),
871                                 errmsg("cannot specify NULL in BINARY mode")));
872
873        /* Set defaults for omitted options */
874        if (!cstate->delim)
875                cstate->delim = cstate->csv_mode ? "," : "\t";
876
877        if (!cstate->null_print)
878                cstate->null_print = cstate->csv_mode ? "" : "\\N";
879        cstate->null_print_len = strlen(cstate->null_print);
880
881        if (cstate->csv_mode)
882        {
883                if (!cstate->quote)
884                        cstate->quote = "\"";
885                if (!cstate->escape)
886                        cstate->escape = cstate->quote;
887        }
888
889        /* Only single-byte delimiter strings are supported. */
890        if (strlen(cstate->delim) != 1)
891                ereport(ERROR,
892                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
893                          errmsg("COPY delimiter must be a single one-byte character")));
894
895        /* Disallow end-of-line characters */
896        if (strchr(cstate->delim, '\r') != NULL ||
897                strchr(cstate->delim, '\n') != NULL)
898                ereport(ERROR,
899                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
900                         errmsg("COPY delimiter cannot be newline or carriage return")));
901
902        if (strchr(cstate->null_print, '\r') != NULL ||
903                strchr(cstate->null_print, '\n') != NULL)
904                ereport(ERROR,
905                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
906                                 errmsg("COPY null representation cannot use newline or carriage return")));
907
908        /*
909         * Disallow unsafe delimiter characters in non-CSV mode.  We can't allow
910         * backslash because it would be ambiguous.  We can't allow the other
911         * cases because data characters matching the delimiter must be
912         * backslashed, and certain backslash combinations are interpreted
913         * non-literally by COPY IN.  Disallowing all lower case ASCII letters is
914         * more than strictly necessary, but seems best for consistency and
915         * future-proofing.  Likewise we disallow all digits though only octal
916         * digits are actually dangerous.
917         */
918        if (!cstate->csv_mode &&
919                strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
920                           cstate->delim[0]) != NULL)
921                ereport(ERROR,
922                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
923                                 errmsg("COPY delimiter cannot be \"%s\"", cstate->delim)));
924
925        /* Check header */
926        if (!cstate->csv_mode && cstate->header_line)
927                ereport(ERROR,
928                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
929                                 errmsg("COPY HEADER available only in CSV mode")));
930
931        /* Check quote */
932        if (!cstate->csv_mode && cstate->quote != NULL)
933                ereport(ERROR,
934                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
935                                 errmsg("COPY quote available only in CSV mode")));
936
937        if (cstate->csv_mode && strlen(cstate->quote) != 1)
938                ereport(ERROR,
939                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
940                                 errmsg("COPY quote must be a single one-byte character")));
941
942        if (cstate->csv_mode && cstate->delim[0] == cstate->quote[0])
943                ereport(ERROR,
944                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
945                                 errmsg("COPY delimiter and quote must be different")));
946
947        /* Check escape */
948        if (!cstate->csv_mode && cstate->escape != NULL)
949                ereport(ERROR,
950                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
951                                 errmsg("COPY escape available only in CSV mode")));
952
953        if (cstate->csv_mode && strlen(cstate->escape) != 1)
954                ereport(ERROR,
955                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
956                                 errmsg("COPY escape must be a single one-byte character")));
957
958        /* Check force_quote */
959        if (!cstate->csv_mode && force_quote != NIL)
960                ereport(ERROR,
961                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
962                                 errmsg("COPY force quote available only in CSV mode")));
963        if (force_quote != NIL && is_from)
964                ereport(ERROR,
965                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
966                                 errmsg("COPY force quote only available using COPY TO")));
967
968        /* Check force_notnull */
969        if (!cstate->csv_mode && force_notnull != NIL)
970                ereport(ERROR,
971                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
972                                 errmsg("COPY force not null available only in CSV mode")));
973        if (force_notnull != NIL && !is_from)
974                ereport(ERROR,
975                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
976                          errmsg("COPY force not null only available using COPY FROM")));
977
978        /* Don't allow the delimiter to appear in the null string. */
979        if (strchr(cstate->null_print, cstate->delim[0]) != NULL)
980                ereport(ERROR,
981                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
982                errmsg("COPY delimiter must not appear in the NULL specification")));
983
984        /* Don't allow the CSV quote char to appear in the null string. */
985        if (cstate->csv_mode &&
986                strchr(cstate->null_print, cstate->quote[0]) != NULL)
987                ereport(ERROR,
988                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
989                                 errmsg("CSV quote character must not appear in the NULL specification")));
990
991        /* Disallow file COPY except to superusers. */
992        if (!pipe && !superuser())
993                ereport(ERROR,
994                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
995                                 errmsg("must be superuser to COPY to or from a file"),
996                                 errhint("Anyone can COPY to stdout or from stdin. "
997                                                 "psql's \\copy command also works for anyone.")));
998
999        if (stmt->relation)
1000        {
1001                Assert(!stmt->query);
1002                cstate->queryDesc = NULL;
1003
1004                /* Open and lock the relation, using the appropriate lock type. */
1005                cstate->rel = heap_openrv(stmt->relation,
1006                                                         (is_from ? RowExclusiveLock : AccessShareLock));
1007
1008                tupDesc = RelationGetDescr(cstate->rel);
1009
1010                /* Check relation permissions. */
1011                relPerms = pg_class_aclmask(RelationGetRelid(cstate->rel), GetUserId(),
1012                                                                        required_access, ACLMASK_ALL);
1013                remainingPerms = required_access & ~relPerms;
1014                if (remainingPerms != 0)
1015                {
1016                        /* We don't have table permissions, check per-column permissions */
1017                        List       *attnums;
1018                        ListCell   *cur;
1019
1020                        attnums = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1021                        foreach(cur, attnums)
1022                        {
1023                                int                     attnum = lfirst_int(cur);
1024
1025                                if (pg_attribute_aclcheck(RelationGetRelid(cstate->rel),
1026                                                                                  attnum,
1027                                                                                  GetUserId(),
1028                                                                                  remainingPerms) != ACLCHECK_OK)
1029                                        aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
1030                                                                   RelationGetRelationName(cstate->rel));
1031                        }
1032                }
1033
1034                /* check read-only transaction */
1035                if (XactReadOnly && is_from && !cstate->rel->rd_islocaltemp)
1036                        ereport(ERROR,
1037                                        (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
1038                                         errmsg("transaction is read-only")));
1039
1040                /* Don't allow COPY w/ OIDs to or from a table without them */
1041                if (cstate->oids && !cstate->rel->rd_rel->relhasoids)
1042                        ereport(ERROR,
1043                                        (errcode(ERRCODE_UNDEFINED_COLUMN),
1044                                         errmsg("table \"%s\" does not have OIDs",
1045                                                        RelationGetRelationName(cstate->rel))));
1046        }
1047        else
1048        {
1049                List       *rewritten;
1050                Query      *query;
1051                PlannedStmt *plan;
1052                DestReceiver *dest;
1053
1054                Assert(!is_from);
1055                cstate->rel = NULL;
1056
1057                /* Don't allow COPY w/ OIDs from a select */
1058                if (cstate->oids)
1059                        ereport(ERROR,
1060                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1061                                         errmsg("COPY (SELECT) WITH OIDS is not supported")));
1062
1063                /*
1064                 * Run parse analysis and rewrite.      Note this also acquires sufficient
1065                 * locks on the source table(s).
1066                 *
1067                 * Because the parser and planner tend to scribble on their input, we
1068                 * make a preliminary copy of the source querytree.  This prevents
1069                 * problems in the case that the COPY is in a portal or plpgsql
1070                 * function and is executed repeatedly.  (See also the same hack in
1071                 * DECLARE CURSOR and PREPARE.)  XXX FIXME someday.
1072                 */
1073                rewritten = pg_analyze_and_rewrite((Node *) copyObject(stmt->query),
1074                                                                                   queryString, NULL, 0);
1075
1076                /* We don't expect more or less than one result query */
1077                if (list_length(rewritten) != 1)
1078                        elog(ERROR, "unexpected rewrite result");
1079
1080                query = (Query *) linitial(rewritten);
1081                Assert(query->commandType == CMD_SELECT);
1082                Assert(query->utilityStmt == NULL);
1083
1084                /* Query mustn't use INTO, either */
1085                if (query->intoClause)
1086                        ereport(ERROR,
1087                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1088                                         errmsg("COPY (SELECT INTO) is not supported")));
1089
1090                /* plan the query */
1091                plan = planner(query, 0, NULL);
1092
1093                /*
1094                 * Use a snapshot with an updated command ID to ensure this query sees
1095                 * results of any previously executed queries.
1096                 */
1097                PushUpdatedSnapshot(GetActiveSnapshot());
1098
1099                /* Create dest receiver for COPY OUT */
1100                dest = CreateDestReceiver(DestCopyOut);
1101                ((DR_copy *) dest)->cstate = cstate;
1102
1103                /* Create a QueryDesc requesting no output */
1104                cstate->queryDesc = CreateQueryDesc(plan, queryString,
1105                                                                                        GetActiveSnapshot(),
1106                                                                                        InvalidSnapshot,
1107                                                                                        dest, NULL, false);
1108
1109                /*
1110                 * Call ExecutorStart to prepare the plan for execution.
1111                 *
1112                 * ExecutorStart computes a result tupdesc for us
1113                 */
1114                ExecutorStart(cstate->queryDesc, 0);
1115
1116                tupDesc = cstate->queryDesc->tupDesc;
1117        }
1118
1119        /* Generate or convert list of attributes to process */
1120        cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1121
1122        num_phys_attrs = tupDesc->natts;
1123
1124        /* Convert FORCE QUOTE name list to per-column flags, check validity */
1125        cstate->force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1126        if (force_quote)
1127        {
1128                List       *attnums;
1129                ListCell   *cur;
1130
1131                attnums = CopyGetAttnums(tupDesc, cstate->rel, force_quote);
1132
1133                foreach(cur, attnums)
1134                {
1135                        int                     attnum = lfirst_int(cur);
1136
1137                        if (!list_member_int(cstate->attnumlist, attnum))
1138                                ereport(ERROR,
1139                                                (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1140                                   errmsg("FORCE QUOTE column \"%s\" not referenced by COPY",
1141                                                  NameStr(tupDesc->attrs[attnum - 1]->attname))));
1142                        cstate->force_quote_flags[attnum - 1] = true;
1143                }
1144        }
1145
1146        /* Convert FORCE NOT NULL name list to per-column flags, check validity */
1147        cstate->force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1148        if (force_notnull)
1149        {
1150                List       *attnums;
1151                ListCell   *cur;
1152
1153                attnums = CopyGetAttnums(tupDesc, cstate->rel, force_notnull);
1154
1155                foreach(cur, attnums)
1156                {
1157                        int                     attnum = lfirst_int(cur);
1158
1159                        if (!list_member_int(cstate->attnumlist, attnum))
1160                                ereport(ERROR,
1161                                                (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1162                                errmsg("FORCE NOT NULL column \"%s\" not referenced by COPY",
1163                                           NameStr(tupDesc->attrs[attnum - 1]->attname))));
1164                        cstate->force_notnull_flags[attnum - 1] = true;
1165                }
1166        }
1167
1168        /* Set up variables to avoid per-attribute overhead. */
1169        initStringInfo(&cstate->attribute_buf);
1170        initStringInfo(&cstate->line_buf);
1171        cstate->line_buf_converted = false;
1172//      cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
1173        cstate->raw_buf = (char *) ((((int) palloc(RAW_BUF_SIZE + 16)) + 15) &~ 0xF);
1174        cstate->raw_buf_index = cstate->raw_buf_len = 0;
1175        cstate->processed = 0;
1176       
1177        /*Initialize bit stream buffers*/
1178        cstate->escape_stream = simd_new(RAW_BUF_SIZE/BLOCK_SIZE_BYTES+1);
1179        cstate->quote_stream = simd_new(RAW_BUF_SIZE/BLOCK_SIZE_BYTES+1);
1180        cstate->delim_stream = simd_new(RAW_BUF_SIZE/BLOCK_SIZE_BYTES+1);
1181        cstate->EOL_stream = simd_new(RAW_BUF_SIZE/BLOCK_SIZE_BYTES+1);
1182        /*
1183         * Set up encoding conversion info.  Even if the client and server
1184         * encodings are the same, we must apply pg_client_to_server() to validate
1185         * data in multibyte encodings.
1186         */
1187        cstate->client_encoding = pg_get_client_encoding();
1188        cstate->need_transcoding =
1189                (cstate->client_encoding != GetDatabaseEncoding() ||
1190                 pg_database_encoding_max_length() > 1);
1191        /* See Multibyte encoding comment above */
1192        cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->client_encoding);
1193
1194        cstate->copy_dest = COPY_FILE;          /* default */
1195        cstate->filename = stmt->filename;
1196#ifdef BUFFER_PROFILING
1197  copy_timer = init_BOM_timer(7067652);
1198  start_BOM_interval(copy_timer);
1199#endif
1200
1201        if (is_from)
1202                CopyFrom(cstate);               /* copy from file to database */
1203        else
1204                DoCopyTo(cstate);               /* copy from database to file */
1205               
1206#ifdef BUFFER_PROFILING
1207    end_BOM_interval(copy_timer);
1208        fprintf(stderr,"copy_timer!\n");
1209        dump_BOM_table(copy_timer);
1210#endif
1211        /*
1212         * Close the relation or query.  If reading, we can release the
1213         * AccessShareLock we got; if writing, we should hold the lock until end
1214         * of transaction to ensure that updates will be committed before lock is
1215         * released.
1216         */
1217        if (cstate->rel)
1218                heap_close(cstate->rel, (is_from ? NoLock : AccessShareLock));
1219        else
1220        {
1221                /* Close down the query and free resources. */
1222                ExecutorEnd(cstate->queryDesc);
1223                FreeQueryDesc(cstate->queryDesc);
1224                PopActiveSnapshot();
1225        }
1226
1227        /* Clean up storage (probably not really necessary) */
1228        processed = cstate->processed;
1229
1230        pfree(cstate->attribute_buf.data);
1231        pfree(cstate->line_buf.data);
1232        pfree(cstate->raw_buf);
1233        pfree(cstate);
1234
1235        return processed;
1236}
1237
1238
1239/*
1240 * This intermediate routine exists mainly to localize the effects of setjmp
1241 * so we don't need to plaster a lot of variables with "volatile".
1242 */
1243static void
1244DoCopyTo(CopyState cstate)
1245{
1246        bool            pipe = (cstate->filename == NULL);
1247
1248        if (cstate->rel)
1249        {
1250                if (cstate->rel->rd_rel->relkind != RELKIND_RELATION)
1251                {
1252                        if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
1253                                ereport(ERROR,
1254                                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1255                                                 errmsg("cannot copy from view \"%s\"",
1256                                                                RelationGetRelationName(cstate->rel)),
1257                                                 errhint("Try the COPY (SELECT ...) TO variant.")));
1258                        else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
1259                                ereport(ERROR,
1260                                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1261                                                 errmsg("cannot copy from sequence \"%s\"",
1262                                                                RelationGetRelationName(cstate->rel))));
1263                        else
1264                                ereport(ERROR,
1265                                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1266                                                 errmsg("cannot copy from non-table relation \"%s\"",
1267                                                                RelationGetRelationName(cstate->rel))));
1268                }
1269        }
1270
1271        if (pipe)
1272        {
1273                if (whereToSendOutput == DestRemote)
1274                        cstate->fe_copy = true;
1275                else
1276                        cstate->copy_file = stdout;
1277        }
1278        else
1279        {
1280                mode_t          oumask;         /* Pre-existing umask value */
1281                struct stat st;
1282
1283                /*
1284                 * Prevent write to relative path ... too easy to shoot oneself in the
1285                 * foot by overwriting a database file ...
1286                 */
1287                if (!is_absolute_path(cstate->filename))
1288                        ereport(ERROR,
1289                                        (errcode(ERRCODE_INVALID_NAME),
1290                                         errmsg("relative path not allowed for COPY to file")));
1291
1292                oumask = umask((mode_t) 022);
1293                cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1294                umask(oumask);
1295
1296                if (cstate->copy_file == NULL)
1297                        ereport(ERROR,
1298                                        (errcode_for_file_access(),
1299                                         errmsg("could not open file \"%s\" for writing: %m",
1300                                                        cstate->filename)));
1301
1302                fstat(fileno(cstate->copy_file), &st);
1303                if (S_ISDIR(st.st_mode))
1304                        ereport(ERROR,
1305                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1306                                         errmsg("\"%s\" is a directory", cstate->filename)));
1307        }
1308
1309        PG_TRY();
1310        {
1311                if (cstate->fe_copy)
1312                        SendCopyBegin(cstate);
1313
1314                CopyTo(cstate);
1315
1316                if (cstate->fe_copy)
1317                        SendCopyEnd(cstate);
1318        }
1319        PG_CATCH();
1320        {
1321                /*
1322                 * Make sure we turn off old-style COPY OUT mode upon error. It is
1323                 * okay to do this in all cases, since it does nothing if the mode is
1324                 * not on.
1325                 */
1326                pq_endcopyout(true);
1327                PG_RE_THROW();
1328        }
1329        PG_END_TRY();
1330
1331        if (!pipe)
1332        {
1333                if (FreeFile(cstate->copy_file))
1334                        ereport(ERROR,
1335                                        (errcode_for_file_access(),
1336                                         errmsg("could not write to file \"%s\": %m",
1337                                                        cstate->filename)));
1338        }
1339}
1340
1341/*
1342 * Copy from relation or query TO file.
1343 */
1344static void
1345CopyTo(CopyState cstate)
1346{
1347        TupleDesc       tupDesc;
1348        int                     num_phys_attrs;
1349        Form_pg_attribute *attr;
1350        ListCell   *cur;
1351
1352        if (cstate->rel)
1353                tupDesc = RelationGetDescr(cstate->rel);
1354        else
1355                tupDesc = cstate->queryDesc->tupDesc;
1356        attr = tupDesc->attrs;
1357        num_phys_attrs = tupDesc->natts;
1358        cstate->null_print_client = cstate->null_print;         /* default */
1359
1360        /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1361        cstate->fe_msgbuf = makeStringInfo();
1362
1363        /* Get info about the columns we need to process. */
1364        cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1365        foreach(cur, cstate->attnumlist)
1366        {
1367                int                     attnum = lfirst_int(cur);
1368                Oid                     out_func_oid;
1369                bool            isvarlena;
1370
1371                if (cstate->binary)
1372                        getTypeBinaryOutputInfo(attr[attnum - 1]->atttypid,
1373                                                                        &out_func_oid,
1374                                                                        &isvarlena);
1375                else
1376                        getTypeOutputInfo(attr[attnum - 1]->atttypid,
1377                                                          &out_func_oid,
1378                                                          &isvarlena);
1379                fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]);
1380        }
1381
1382        /*
1383         * Create a temporary memory context that we can reset once per row to
1384         * recover palloc'd memory.  This avoids any problems with leaks inside
1385         * datatype output routines, and should be faster than retail pfree's
1386         * anyway.      (We don't need a whole econtext as CopyFrom does.)
1387         */
1388        cstate->rowcontext = AllocSetContextCreate(CurrentMemoryContext,
1389                                                                                           "COPY TO",
1390                                                                                           ALLOCSET_DEFAULT_MINSIZE,
1391                                                                                           ALLOCSET_DEFAULT_INITSIZE,
1392                                                                                           ALLOCSET_DEFAULT_MAXSIZE);
1393
1394        if (cstate->binary)
1395        {
1396                /* Generate header for a binary copy */
1397                int32           tmp;
1398
1399                /* Signature */
1400                CopySendData(cstate, (char *) BinarySignature, 11);
1401                /* Flags field */
1402                tmp = 0;
1403                if (cstate->oids)
1404                        tmp |= (1 << 16);
1405                CopySendInt32(cstate, tmp);
1406                /* No header extension */
1407                tmp = 0;
1408                CopySendInt32(cstate, tmp);
1409        }
1410        else
1411        {
1412                /*
1413                 * For non-binary copy, we need to convert null_print to client
1414                 * encoding, because it will be sent directly with CopySendString.
1415                 */
1416                if (cstate->need_transcoding)
1417                        cstate->null_print_client = pg_server_to_client(cstate->null_print,
1418                                                                                                         cstate->null_print_len);
1419
1420                /* if a header has been requested send the line */
1421                if (cstate->header_line)
1422                {
1423                        bool            hdr_delim = false;
1424
1425                        foreach(cur, cstate->attnumlist)
1426                        {
1427                                int                     attnum = lfirst_int(cur);
1428                                char       *colname;
1429
1430                                if (hdr_delim)
1431                                        CopySendChar(cstate, cstate->delim[0]);
1432                                hdr_delim = true;
1433
1434                                colname = NameStr(attr[attnum - 1]->attname);
1435
1436                                CopyAttributeOutCSV(cstate, colname, false,
1437                                                                        list_length(cstate->attnumlist) == 1);
1438                        }
1439
1440                        CopySendEndOfRow(cstate);
1441                }
1442        }
1443
1444        if (cstate->rel)
1445        {
1446                Datum      *values;
1447                bool       *nulls;
1448                HeapScanDesc scandesc;
1449                HeapTuple       tuple;
1450
1451                values = (Datum *) palloc(num_phys_attrs * sizeof(Datum));
1452                nulls = (bool *) palloc(num_phys_attrs * sizeof(bool));
1453
1454                scandesc = heap_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL);
1455
1456                while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL)
1457                {
1458                        CHECK_FOR_INTERRUPTS();
1459
1460                        /* Deconstruct the tuple ... faster than repeated heap_getattr */
1461                        heap_deform_tuple(tuple, tupDesc, values, nulls);
1462
1463                        /* Format and send the data */
1464                        CopyOneRowTo(cstate, HeapTupleGetOid(tuple), values, nulls);
1465                }
1466
1467                heap_endscan(scandesc);
1468        }
1469        else
1470        {
1471                /* run the plan --- the dest receiver will send tuples */
1472                ExecutorRun(cstate->queryDesc, ForwardScanDirection, 0L);
1473        }
1474
1475        if (cstate->binary)
1476        {
1477                /* Generate trailer for a binary copy */
1478                CopySendInt16(cstate, -1);
1479                /* Need to flush out the trailer */
1480                CopySendEndOfRow(cstate);
1481        }
1482
1483        MemoryContextDelete(cstate->rowcontext);
1484}
1485
1486/*
1487 * Emit one row during CopyTo().
1488 */
1489static void
1490CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls)
1491{
1492        bool            need_delim = false;
1493        FmgrInfo   *out_functions = cstate->out_functions;
1494        MemoryContext oldcontext;
1495        ListCell   *cur;
1496        char       *string;
1497
1498        MemoryContextReset(cstate->rowcontext);
1499        oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1500
1501        if (cstate->binary)
1502        {
1503                /* Binary per-tuple header */
1504                CopySendInt16(cstate, list_length(cstate->attnumlist));
1505                /* Send OID if wanted --- note attnumlist doesn't include it */
1506                if (cstate->oids)
1507                {
1508                        /* Hack --- assume Oid is same size as int32 */
1509                        CopySendInt32(cstate, sizeof(int32));
1510                        CopySendInt32(cstate, tupleOid);
1511                }
1512        }
1513        else
1514        {
1515                /* Text format has no per-tuple header, but send OID if wanted */
1516                /* Assume digits don't need any quoting or encoding conversion */
1517                if (cstate->oids)
1518                {
1519                        string = DatumGetCString(DirectFunctionCall1(oidout,
1520                                                                                                ObjectIdGetDatum(tupleOid)));
1521                        CopySendString(cstate, string);
1522                        need_delim = true;
1523                }
1524        }
1525
1526        foreach(cur, cstate->attnumlist)
1527        {
1528                int                     attnum = lfirst_int(cur);
1529                Datum           value = values[attnum - 1];
1530                bool            isnull = nulls[attnum - 1];
1531
1532                if (!cstate->binary)
1533                {
1534                        if (need_delim)
1535                                CopySendChar(cstate, cstate->delim[0]);
1536                        need_delim = true;
1537                }
1538
1539                if (isnull)
1540                {
1541                        if (!cstate->binary)
1542                                CopySendString(cstate, cstate->null_print_client);
1543                        else
1544                                CopySendInt32(cstate, -1);
1545                }
1546                else
1547                {
1548                        if (!cstate->binary)
1549                        {
1550                                string = OutputFunctionCall(&out_functions[attnum - 1],
1551                                                                                        value);
1552                                if (cstate->csv_mode)
1553                                        CopyAttributeOutCSV(cstate, string,
1554                                                                                cstate->force_quote_flags[attnum - 1],
1555                                                                                list_length(cstate->attnumlist) == 1);
1556                                else
1557                                        CopyAttributeOutText(cstate, string);
1558                        }
1559                        else
1560                        {
1561                                bytea      *outputbytes;
1562
1563                                outputbytes = SendFunctionCall(&out_functions[attnum - 1],
1564                                                                                           value);
1565                                CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
1566                                CopySendData(cstate, VARDATA(outputbytes),
1567                                                         VARSIZE(outputbytes) - VARHDRSZ);
1568                        }
1569                }
1570        }
1571
1572        CopySendEndOfRow(cstate);
1573
1574        MemoryContextSwitchTo(oldcontext);
1575
1576        cstate->processed++;
1577}
1578
1579
1580/*
1581 * error context callback for COPY FROM
1582 */
1583static void
1584copy_in_error_callback(void *arg)
1585{
1586        CopyState       cstate = (CopyState) arg;
1587
1588        if (cstate->binary)
1589        {
1590                /* can't usefully display the data */
1591                if (cstate->cur_attname)
1592                        errcontext("COPY %s, line %d, column %s",
1593                                           cstate->cur_relname, cstate->cur_lineno,
1594                                           cstate->cur_attname);
1595                else
1596                        errcontext("COPY %s, line %d",
1597                                           cstate->cur_relname, cstate->cur_lineno);
1598        }
1599        else
1600        {
1601                if (cstate->cur_attname && cstate->cur_attval)
1602                {
1603                        /* error is relevant to a particular column */
1604                        char       *attval;
1605
1606                        attval = limit_printout_length(cstate->cur_attval);
1607                        errcontext("COPY %s, line %d, column %s: \"%s\"",
1608                                           cstate->cur_relname, cstate->cur_lineno,
1609                                           cstate->cur_attname, attval);
1610                        pfree(attval);
1611                }
1612                else if (cstate->cur_attname)
1613                {
1614                        /* error is relevant to a particular column, value is NULL */
1615                        errcontext("COPY %s, line %d, column %s: null input",
1616                                           cstate->cur_relname, cstate->cur_lineno,
1617                                           cstate->cur_attname);
1618                }
1619                else
1620                {
1621                        /* error is relevant to a particular line */
1622                        if (cstate->line_buf_converted || !cstate->need_transcoding)
1623                        {
1624                                char       *lineval;
1625
1626                                lineval = limit_printout_length(cstate->line_buf.data);
1627                                errcontext("COPY %s, line %d: \"%s\"",
1628                                                   cstate->cur_relname, cstate->cur_lineno, lineval);
1629                                pfree(lineval);
1630                        }
1631                        else
1632                        {
1633                                /*
1634                                 * Here, the line buffer is still in a foreign encoding, and
1635                                 * indeed it's quite likely that the error is precisely a
1636                                 * failure to do encoding conversion (ie, bad data).  We dare
1637                                 * not try to convert it, and at present there's no way to
1638                                 * regurgitate it without conversion.  So we have to punt and
1639                                 * just report the line number.
1640                                 */
1641                                errcontext("COPY %s, line %d",
1642                                                   cstate->cur_relname, cstate->cur_lineno);
1643                        }
1644                }
1645        }
1646}
1647
1648/*
1649 * Make sure we don't print an unreasonable amount of COPY data in a message.
1650 *
1651 * It would seem a lot easier to just use the sprintf "precision" limit to
1652 * truncate the string.  However, some versions of glibc have a bug/misfeature
1653 * that vsnprintf will always fail (return -1) if it is asked to truncate
1654 * a string that contains invalid byte sequences for the current encoding.
1655 * So, do our own truncation.  We return a pstrdup'd copy of the input.
1656 */
1657static char *
1658limit_printout_length(const char *str)
1659{
1660#define MAX_COPY_DATA_DISPLAY 100
1661
1662        int                     slen = strlen(str);
1663        int                     len;
1664        char       *res;
1665
1666        /* Fast path if definitely okay */
1667        if (slen <= MAX_COPY_DATA_DISPLAY)
1668                return pstrdup(str);
1669
1670        /* Apply encoding-dependent truncation */
1671        len = pg_mbcliplen(str, slen, MAX_COPY_DATA_DISPLAY);
1672
1673        /*
1674         * Truncate, and add "..." to show we truncated the input.
1675         */
1676        res = (char *) palloc(len + 4);
1677        memcpy(res, str, len);
1678        strcpy(res + len, "...");
1679
1680        return res;
1681}
1682
1683/*
1684 * Copy FROM file to relation.
1685 */
1686static void
1687CopyFrom(CopyState cstate)
1688{
1689        bool            pipe = (cstate->filename == NULL);
1690        HeapTuple       tuple;
1691        TupleDesc       tupDesc;
1692        Form_pg_attribute *attr;
1693        AttrNumber      num_phys_attrs,
1694                                attr_count,
1695                                num_defaults;
1696        FmgrInfo   *in_functions;
1697        FmgrInfo        oid_in_function;
1698        Oid                *typioparams;
1699        Oid                     oid_typioparam;
1700        int                     attnum;
1701        int                     i;
1702        Oid                     in_func_oid;
1703        Datum      *values;
1704        bool       *nulls;
1705        int                     nfields;
1706        char      **field_strings;
1707        bool            done = false;
1708        bool            isnull;
1709        ResultRelInfo *resultRelInfo;
1710        EState     *estate = CreateExecutorState(); /* for ExecConstraints() */
1711        TupleTableSlot *slot;
1712        bool            file_has_oids;
1713        int                *defmap;
1714        ExprState **defexprs;           /* array of default att expressions */
1715        ExprContext *econtext;          /* used for ExecEvalExpr for default atts */
1716        MemoryContext oldcontext = CurrentMemoryContext;
1717        ErrorContextCallback errcontext;
1718        CommandId       mycid = GetCurrentCommandId(true);
1719        int                     hi_options = 0; /* start with default heap_insert options */
1720        BulkInsertState bistate;
1721
1722#ifdef BUFFER_PROFILING
1723  copyloadrawbuf_timer = init_BOM_timer(RAW_BUF_SIZE);
1724  bitstreamgen_timer = init_BOM_timer(RAW_BUF_SIZE);
1725  readline_timer = init_BOM_timer(128);
1726  readattr_timer = init_BOM_timer(128);
1727  userattr_timer = init_BOM_timer(128);
1728  tupleattr_timer = init_BOM_timer(128);
1729  loop_timer = init_BOM_timer(128);
1730#endif
1731
1732        Assert(cstate->rel);
1733
1734        if (cstate->rel->rd_rel->relkind != RELKIND_RELATION)
1735        {
1736                if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
1737                        ereport(ERROR,
1738                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1739                                         errmsg("cannot copy to view \"%s\"",
1740                                                        RelationGetRelationName(cstate->rel))));
1741                else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
1742                        ereport(ERROR,
1743                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1744                                         errmsg("cannot copy to sequence \"%s\"",
1745                                                        RelationGetRelationName(cstate->rel))));
1746                else
1747                        ereport(ERROR,
1748                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1749                                         errmsg("cannot copy to non-table relation \"%s\"",
1750                                                        RelationGetRelationName(cstate->rel))));
1751        }
1752
1753        /*----------
1754         * Check to see if we can avoid writing WAL
1755         *
1756         * If archive logging is not enabled *and* either
1757         *      - table was created in same transaction as this COPY
1758         *      - data is being written to relfilenode created in this transaction
1759         * then we can skip writing WAL.  It's safe because if the transaction
1760         * doesn't commit, we'll discard the table (or the new relfilenode file).
1761         * If it does commit, we'll have done the heap_sync at the bottom of this
1762         * routine first.
1763         *
1764         * As mentioned in comments in utils/rel.h, the in-same-transaction test
1765         * is not completely reliable, since in rare cases rd_createSubid or
1766         * rd_newRelfilenodeSubid can be cleared before the end of the transaction.
1767         * However this is OK since at worst we will fail to make the optimization.
1768         *
1769         * Also, if the target file is new-in-transaction, we assume that checking
1770         * FSM for free space is a waste of time, even if we must use WAL because
1771         * of archiving.  This could possibly be wrong, but it's unlikely.
1772         *
1773         * The comments for heap_insert and RelationGetBufferForTuple specify that
1774         * skipping WAL logging is only safe if we ensure that our tuples do not
1775         * go into pages containing tuples from any other transactions --- but this
1776         * must be the case if we have a new table or new relfilenode, so we need
1777         * no additional work to enforce that.
1778         *----------
1779         */
1780        if (cstate->rel->rd_createSubid != InvalidSubTransactionId ||
1781                cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)
1782        {
1783                hi_options |= HEAP_INSERT_SKIP_FSM;
1784                if (!XLogArchivingActive())
1785                        hi_options |= HEAP_INSERT_SKIP_WAL;
1786        }
1787
1788        if (pipe)
1789        {
1790                if (whereToSendOutput == DestRemote)
1791                        ReceiveCopyBegin(cstate);
1792                else
1793                        cstate->copy_file = stdin;
1794        }
1795        else
1796        {
1797                struct stat st;
1798
1799                cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
1800
1801                if (cstate->copy_file == NULL)
1802                        ereport(ERROR,
1803                                        (errcode_for_file_access(),
1804                                         errmsg("could not open file \"%s\" for reading: %m",
1805                                                        cstate->filename)));
1806
1807                fstat(fileno(cstate->copy_file), &st);
1808                if (S_ISDIR(st.st_mode))
1809                        ereport(ERROR,
1810                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1811                                         errmsg("\"%s\" is a directory", cstate->filename)));
1812        }
1813
1814        tupDesc = RelationGetDescr(cstate->rel);
1815        attr = tupDesc->attrs;
1816        num_phys_attrs = tupDesc->natts;
1817        attr_count = list_length(cstate->attnumlist);
1818        num_defaults = 0;
1819
1820        /*
1821         * We need a ResultRelInfo so we can use the regular executor's
1822         * index-entry-making machinery.  (There used to be a huge amount of code
1823         * here that basically duplicated execUtils.c ...)
1824         */
1825        resultRelInfo = makeNode(ResultRelInfo);
1826        resultRelInfo->ri_RangeTableIndex = 1;          /* dummy */
1827        resultRelInfo->ri_RelationDesc = cstate->rel;
1828        resultRelInfo->ri_TrigDesc = CopyTriggerDesc(cstate->rel->trigdesc);
1829        if (resultRelInfo->ri_TrigDesc)
1830                resultRelInfo->ri_TrigFunctions = (FmgrInfo *)
1831                        palloc0(resultRelInfo->ri_TrigDesc->numtriggers * sizeof(FmgrInfo));
1832        resultRelInfo->ri_TrigInstrument = NULL;
1833
1834        ExecOpenIndices(resultRelInfo);
1835
1836        estate->es_result_relations = resultRelInfo;
1837        estate->es_num_result_relations = 1;
1838        estate->es_result_relation_info = resultRelInfo;
1839
1840        /* Set up a tuple slot too */
1841        slot = MakeSingleTupleTableSlot(tupDesc);
1842
1843        econtext = GetPerTupleExprContext(estate);
1844
1845        /*
1846         * Pick up the required catalog information for each attribute in the
1847         * relation, including the input function, the element type (to pass to
1848         * the input function), and info about defaults and constraints. (Which
1849         * input function we use depends on text/binary format choice.)
1850         */
1851        in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1852        typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
1853        defmap = (int *) palloc(num_phys_attrs * sizeof(int));
1854        defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
1855
1856        for (attnum = 1; attnum <= num_phys_attrs; attnum++)
1857        {
1858                /* We don't need info for dropped attributes */
1859                if (attr[attnum - 1]->attisdropped)
1860                        continue;
1861
1862                /* Fetch the input function and typioparam info */
1863                if (cstate->binary)
1864                        getTypeBinaryInputInfo(attr[attnum - 1]->atttypid,
1865                                                                   &in_func_oid, &typioparams[attnum - 1]);
1866                else
1867                        getTypeInputInfo(attr[attnum - 1]->atttypid,
1868                                                         &in_func_oid, &typioparams[attnum - 1]);
1869                fmgr_info(in_func_oid, &in_functions[attnum - 1]);
1870
1871                /* Get default info if needed */
1872                if (!list_member_int(cstate->attnumlist, attnum))
1873                {
1874                        /* attribute is NOT to be copied from input */
1875                        /* use default value if one exists */
1876                        Node       *defexpr = build_column_default(cstate->rel, attnum);
1877
1878                        if (defexpr != NULL)
1879                        {
1880                                defexprs[num_defaults] = ExecPrepareExpr((Expr *) defexpr,
1881                                                                                                                 estate);
1882                                defmap[num_defaults] = attnum - 1;
1883                                num_defaults++;
1884                        }
1885                }
1886        }
1887
1888        /* Prepare to catch AFTER triggers. */
1889        AfterTriggerBeginQuery();
1890
1891        /*
1892         * Check BEFORE STATEMENT insertion triggers. It's debateable whether we
1893         * should do this for COPY, since it's not really an "INSERT" statement as
1894         * such. However, executing these triggers maintains consistency with the
1895         * EACH ROW triggers that we already fire on COPY.
1896         */
1897        ExecBSInsertTriggers(estate, resultRelInfo);
1898
1899        if (!cstate->binary)
1900                file_has_oids = cstate->oids;   /* must rely on user to tell us... */
1901        else
1902        {
1903                /* Read and verify binary header */
1904                char            readSig[11];
1905                int32           tmp;
1906
1907                /* Signature */
1908                if (CopyGetData(cstate, readSig, 11, 11) != 11 ||
1909                        memcmp(readSig, BinarySignature, 11) != 0)
1910                        ereport(ERROR,
1911                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
1912                                         errmsg("COPY file signature not recognized")));
1913                /* Flags field */
1914                if (!CopyGetInt32(cstate, &tmp))
1915                        ereport(ERROR,
1916                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
1917                                         errmsg("invalid COPY file header (missing flags)")));
1918                file_has_oids = (tmp & (1 << 16)) != 0;
1919                tmp &= ~(1 << 16);
1920                if ((tmp >> 16) != 0)
1921                        ereport(ERROR,
1922                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
1923                                 errmsg("unrecognized critical flags in COPY file header")));
1924                /* Header extension length */
1925                if (!CopyGetInt32(cstate, &tmp) ||
1926                        tmp < 0)
1927                        ereport(ERROR,
1928                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
1929                                         errmsg("invalid COPY file header (missing length)")));
1930                /* Skip extension header, if present */
1931                while (tmp-- > 0)
1932                {
1933                        if (CopyGetData(cstate, readSig, 1, 1) != 1)
1934                                ereport(ERROR,
1935                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
1936                                                 errmsg("invalid COPY file header (wrong length)")));
1937                }
1938        }
1939
1940        if (file_has_oids && cstate->binary)
1941        {
1942                getTypeBinaryInputInfo(OIDOID,
1943                                                           &in_func_oid, &oid_typioparam);
1944                fmgr_info(in_func_oid, &oid_in_function);
1945        }
1946
1947        values = (Datum *) palloc(num_phys_attrs * sizeof(Datum));
1948        nulls = (bool *) palloc(num_phys_attrs * sizeof(bool));
1949
1950        /* create workspace for CopyReadAttributes results */
1951        nfields = file_has_oids ? (attr_count + 1) : attr_count;
1952        field_strings = (char **) palloc(nfields * sizeof(char *));
1953
1954        /* Initialize state variables */
1955        cstate->fe_eof = false;
1956        cstate->eol_type = EOL_UNKNOWN;
1957        cstate->cur_relname = RelationGetRelationName(cstate->rel);
1958        cstate->cur_lineno = 0;
1959        cstate->cur_attname = NULL;
1960        cstate->cur_attval = NULL;
1961
1962        bistate = GetBulkInsertState();
1963
1964        /* Set up callback to identify error line number */
1965        errcontext.callback = copy_in_error_callback;
1966        errcontext.arg = (void *) cstate;
1967        errcontext.previous = error_context_stack;
1968        error_context_stack = &errcontext;
1969
1970        /* on input just throw the header line away */
1971        if (cstate->header_line)
1972        {
1973                cstate->cur_lineno++;
1974                done = CopyReadLine(cstate);
1975        }
1976
1977        while (!done)
1978        {
1979#ifdef BUFFER_PROFILING
1980    start_BOM_interval(loop_timer);
1981#endif
1982                bool            skip_tuple;
1983                Oid                     loaded_oid = InvalidOid;
1984
1985                CHECK_FOR_INTERRUPTS();
1986
1987                cstate->cur_lineno++;
1988
1989                /* Reset the per-tuple exprcontext */
1990                ResetPerTupleExprContext(estate);
1991
1992                /* Switch into its memory context */
1993                MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
1994
1995                /* Initialize all values for row to NULL */
1996                MemSet(values, 0, num_phys_attrs * sizeof(Datum));
1997                MemSet(nulls, true, num_phys_attrs * sizeof(bool));
1998
1999                if (!cstate->binary)
2000                {
2001                        ListCell   *cur;
2002                        int                     fldct;
2003                        int                     fieldno;
2004                        char       *string;
2005#ifdef BUFFER_PROFILING
2006    start_BOM_interval(readline_timer);
2007#endif
2008                        /* Actually read the line into memory here */
2009                        done = CopyReadLine(cstate);
2010
2011#ifdef BUFFER_PROFILING
2012    end_BOM_interval(readline_timer);
2013#endif
2014                        /*
2015                         * EOF at start of line means we're done.  If we see EOF after
2016                         * some characters, we act as though it was newline followed by
2017                         * EOF, ie, process the line and then exit loop on next iteration.
2018                         */
2019                        if (done && cstate->line_buf.len == 0)
2020                                break;
2021                               
2022#ifdef BUFFER_PROFILING
2023    start_BOM_interval(readattr_timer);
2024#endif
2025                        /* Parse the line into de-escaped field values */
2026                        if (cstate->csv_mode)
2027                                fldct = CopyReadAttributesCSV(cstate, nfields, field_strings);
2028                        else
2029                                fldct = CopyReadAttributesText(cstate, nfields, field_strings);
2030#ifdef BUFFER_PROFILING
2031    end_BOM_interval(readattr_timer);
2032#endif                         
2033
2034                        fieldno = 0;
2035
2036                        /* Read the OID field if present */
2037                        if (file_has_oids)
2038                        {
2039                                if (fieldno >= fldct)
2040                                        ereport(ERROR,
2041                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2042                                                         errmsg("missing data for OID column")));
2043                                string = field_strings[fieldno++];
2044
2045                                if (string == NULL)
2046                                        ereport(ERROR,
2047                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2048                                                         errmsg("null OID in COPY data")));
2049                                else
2050                                {
2051                                        cstate->cur_attname = "oid";
2052                                        cstate->cur_attval = string;
2053                                        loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin,
2054                                                                                                   CStringGetDatum(string)));
2055                                        if (loaded_oid == InvalidOid)
2056                                                ereport(ERROR,
2057                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2058                                                                 errmsg("invalid OID in COPY data")));
2059                                        cstate->cur_attname = NULL;
2060                                        cstate->cur_attval = NULL;
2061                                }
2062                        }
2063#ifdef BUFFER_PROFILING
2064    start_BOM_interval(userattr_timer);
2065#endif
2066                        /* Loop to read the user attributes on the line. */
2067                        foreach(cur, cstate->attnumlist)
2068                        {
2069                                int                     attnum = lfirst_int(cur);
2070                                int                     m = attnum - 1;
2071
2072                                if (fieldno >= fldct)
2073                                        ereport(ERROR,
2074                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2075                                                         errmsg("missing data for column \"%s\"",
2076                                                                        NameStr(attr[m]->attname))));
2077                                string = field_strings[fieldno++];
2078
2079                                if (cstate->csv_mode && string == NULL &&
2080                                        cstate->force_notnull_flags[m])
2081                                {
2082                                        /* Go ahead and read the NULL string */
2083                                        string = cstate->null_print;
2084                                }
2085
2086                                cstate->cur_attname = NameStr(attr[m]->attname);
2087                                cstate->cur_attval = string;
2088                                values[m] = InputFunctionCall(&in_functions[m],
2089                                                                                          string,
2090                                                                                          typioparams[m],
2091                                                                                          attr[m]->atttypmod);
2092                                if (string != NULL)
2093                                        nulls[m] = false;
2094                                cstate->cur_attname = NULL;
2095                                cstate->cur_attval = NULL;
2096                        }
2097#ifdef BUFFER_PROFILING
2098    end_BOM_interval(userattr_timer);
2099#endif 
2100                        Assert(fieldno == nfields);
2101                }
2102                else
2103                {
2104                        /* binary */
2105                        int16           fld_count;
2106                        ListCell   *cur;
2107
2108                        if (!CopyGetInt16(cstate, &fld_count) ||
2109                                fld_count == -1)
2110                        {
2111                                done = true;
2112                                break;
2113                        }
2114
2115                        if (fld_count != attr_count)
2116                                ereport(ERROR,
2117                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2118                                                 errmsg("row field count is %d, expected %d",
2119                                                                (int) fld_count, attr_count)));
2120
2121                        if (file_has_oids)
2122                        {
2123                                cstate->cur_attname = "oid";
2124                                loaded_oid =
2125                                        DatumGetObjectId(CopyReadBinaryAttribute(cstate,
2126                                                                                                                         0,
2127                                                                                                                         &oid_in_function,
2128                                                                                                                         oid_typioparam,
2129                                                                                                                         -1,
2130                                                                                                                         &isnull));
2131                                if (isnull || loaded_oid == InvalidOid)
2132                                        ereport(ERROR,
2133                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2134                                                         errmsg("invalid OID in COPY data")));
2135                                cstate->cur_attname = NULL;
2136                        }
2137
2138                        i = 0;
2139                        foreach(cur, cstate->attnumlist)
2140                        {
2141                                int                     attnum = lfirst_int(cur);
2142                                int                     m = attnum - 1;
2143
2144                                cstate->cur_attname = NameStr(attr[m]->attname);
2145                                i++;
2146                                values[m] = CopyReadBinaryAttribute(cstate,
2147                                                                                                        i,
2148                                                                                                        &in_functions[m],
2149                                                                                                        typioparams[m],
2150                                                                                                        attr[m]->atttypmod,
2151                                                                                                        &nulls[m]);
2152                                cstate->cur_attname = NULL;
2153                        }
2154                }
2155
2156                /*
2157                 * Now compute and insert any defaults available for the columns not
2158                 * provided by the input data.  Anything not processed here or above
2159                 * will remain NULL.
2160                 */
2161                for (i = 0; i < num_defaults; i++)
2162                {
2163                        values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
2164                                                                                         &nulls[defmap[i]], NULL);
2165                }
2166
2167                /* And now we can form the input tuple. */
2168                tuple = heap_form_tuple(tupDesc, values, nulls);
2169
2170                if (cstate->oids && file_has_oids)
2171                        HeapTupleSetOid(tuple, loaded_oid);
2172
2173                /* Triggers and stuff need to be invoked in query context. */
2174                MemoryContextSwitchTo(oldcontext);
2175#ifdef BUFFER_PROFILING
2176    start_BOM_interval(tupleattr_timer);
2177#endif 
2178
2179                skip_tuple = false;
2180
2181                /* BEFORE ROW INSERT Triggers */
2182                if (resultRelInfo->ri_TrigDesc &&
2183                  resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
2184                {
2185                        HeapTuple       newtuple;
2186
2187                        newtuple = ExecBRInsertTriggers(estate, resultRelInfo, tuple);
2188
2189                        if (newtuple == NULL)           /* "do nothing" */
2190                                skip_tuple = true;
2191                        else if (newtuple != tuple) /* modified by Trigger(s) */
2192                        {
2193                                heap_freetuple(tuple);
2194                                tuple = newtuple;
2195                        }
2196                }
2197
2198                if (!skip_tuple)
2199                {
2200                        /* Place tuple in tuple slot */
2201                        ExecStoreTuple(tuple, slot, InvalidBuffer, false);
2202
2203                        /* Check the constraints of the tuple */
2204                        if (cstate->rel->rd_att->constr)
2205                                ExecConstraints(resultRelInfo, slot, estate);
2206
2207                        /* OK, store the tuple and create index entries for it */
2208                        heap_insert(cstate->rel, tuple, mycid, hi_options, bistate);
2209
2210                        if (resultRelInfo->ri_NumIndices > 0)
2211                                ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
2212
2213                        /* AFTER ROW INSERT Triggers */
2214                        ExecARInsertTriggers(estate, resultRelInfo, tuple);
2215
2216                        /*
2217                         * We count only tuples not suppressed by a BEFORE INSERT trigger;
2218                         * this is the same definition used by execMain.c for counting
2219                         * tuples inserted by an INSERT command.
2220                         */
2221                        cstate->processed++;
2222                }
2223#ifdef BUFFER_PROFILING
2224    end_BOM_interval(tupleattr_timer);
2225#endif 
2226#ifdef BUFFER_PROFILING
2227    end_BOM_interval(loop_timer);
2228#endif 
2229        }
2230
2231        /* Done, clean up */
2232        error_context_stack = errcontext.previous;
2233
2234        FreeBulkInsertState(bistate);
2235
2236        MemoryContextSwitchTo(oldcontext);
2237
2238        /* Execute AFTER STATEMENT insertion triggers */
2239        ExecASInsertTriggers(estate, resultRelInfo);
2240
2241        /* Handle queued AFTER triggers */
2242        AfterTriggerEndQuery(estate);
2243
2244        pfree(values);
2245        pfree(nulls);
2246        pfree(field_strings);
2247
2248        pfree(in_functions);
2249        pfree(typioparams);
2250        pfree(defmap);
2251        pfree(defexprs);
2252
2253        ExecDropSingleTupleTableSlot(slot);
2254
2255        ExecCloseIndices(resultRelInfo);
2256
2257        FreeExecutorState(estate);
2258
2259        if (!pipe)
2260        {
2261                if (FreeFile(cstate->copy_file))
2262                        ereport(ERROR,
2263                                        (errcode_for_file_access(),
2264                                         errmsg("could not read from file \"%s\": %m",
2265                                                        cstate->filename)));
2266        }
2267
2268        /*
2269         * If we skipped writing WAL, then we need to sync the heap (but not
2270         * indexes since those use WAL anyway)
2271         */
2272        if (hi_options & HEAP_INSERT_SKIP_WAL)
2273                heap_sync(cstate->rel);
2274       
2275#ifdef BUFFER_PROFILING
2276//  FILE * timerout;
2277//  timerout = fopen("/home/lindanl/workspace/postgres-csv/installdir/timerout","w");
2278  fprintf(stderr,"copyloadrawbuf_timer!\n");
2279  dump_BOM_table(copyloadrawbuf_timer);
2280  fprintf(stderr,"bitstreamgen_timer!\n");
2281  dump_BOM_table(bitstreamgen_timer);
2282  fprintf(stderr,"readline_timer!\n");
2283  dump_BOM_table(readline_timer);
2284  fprintf(stderr,"readattr_timer!\n");
2285  dump_BOM_table(readattr_timer);
2286  fprintf(stderr,"userattr_timer!\n");
2287  dump_BOM_table(userattr_timer);
2288//  fclose(timerout);
2289  fprintf(stderr,"tupleattr_timer!\n");
2290  dump_BOM_table(tupleattr_timer);
2291  fprintf(stderr,"loop_timer!\n");
2292  dump_BOM_table(loop_timer);
2293#endif
2294}
2295
2296
2297/*
2298 * Read the next input line and stash it in line_buf, with conversion to
2299 * server encoding.
2300 *
2301 * Result is true if read was terminated by EOF, false if terminated
2302 * by newline.  The terminating newline or EOF marker is not included
2303 * in the final value of line_buf.
2304 */
2305static bool
2306CopyReadLine(CopyState cstate)
2307{
2308        bool            result;
2309
2310        resetStringInfo(&cstate->line_buf);
2311
2312        /* Mark that encoding conversion hasn't occurred yet */
2313        cstate->line_buf_converted = false;
2314
2315        /* Parse data and transfer into line_buf */
2316        result = CopyReadLineText(cstate);
2317
2318        if (result)
2319        {
2320                /*
2321                 * Reached EOF.  In protocol version 3, we should ignore anything
2322                 * after \. up to the protocol end of copy data.  (XXX maybe better
2323                 * not to treat \. as special?)
2324                 */
2325                if (cstate->copy_dest == COPY_NEW_FE)
2326                {
2327                        do
2328                        {
2329                                cstate->raw_buf_index = cstate->raw_buf_len;
2330                        } while (CopyLoadRawBuf(cstate));
2331                }
2332        }
2333        else
2334        {
2335                /*
2336                 * If we didn't hit EOF, then we must have transferred the EOL marker
2337                 * to line_buf along with the data.  Get rid of it.
2338                 */
2339                switch (cstate->eol_type)
2340                {
2341                        case EOL_NL:
2342                                Assert(cstate->line_buf.len >= 1);
2343                                Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\n');
2344                                cstate->line_buf.len--;
2345                                cstate->line_buf.data[cstate->line_buf.len] = '\0';
2346                                break;
2347                        case EOL_CR:
2348                                Assert(cstate->line_buf.len >= 1);
2349                                Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\r');
2350                                cstate->line_buf.len--;
2351                                cstate->line_buf.data[cstate->line_buf.len] = '\0';
2352                                break;
2353                        case EOL_CRNL:
2354                                Assert(cstate->line_buf.len >= 2);
2355                                Assert(cstate->line_buf.data[cstate->line_buf.len - 2] == '\r');
2356                                Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\n');
2357                                cstate->line_buf.len -= 2;
2358                                cstate->line_buf.data[cstate->line_buf.len] = '\0';
2359                                break;
2360                        case EOL_UNKNOWN:
2361                                /* shouldn't get here */
2362                                Assert(false);
2363                                break;
2364                }
2365        }
2366
2367        /* Done reading the line.  Convert it to server encoding. */
2368        if (cstate->need_transcoding)
2369        {
2370                char       *cvt;
2371
2372                cvt = pg_client_to_server(cstate->line_buf.data,
2373                                                                  cstate->line_buf.len);
2374                if (cvt != cstate->line_buf.data)
2375                {
2376                        /* transfer converted data back to line_buf */
2377                        resetStringInfo(&cstate->line_buf);
2378                        appendBinaryStringInfo(&cstate->line_buf, cvt, strlen(cvt));
2379                        pfree(cvt);
2380                }
2381        }
2382
2383        /* Now it's safe to use the buffer in error messages */
2384        cstate->line_buf_converted = true;
2385
2386        return result;
2387}
2388#ifndef BITSTREAM
2389/*
2390 * CopyReadLineText - inner loop of CopyReadLine for text mode
2391 */
2392static bool
2393CopyReadLineText(CopyState cstate)
2394{
2395        char       *copy_raw_buf;
2396        int                     raw_buf_ptr;
2397        int                     copy_buf_len;
2398        bool            need_data = false;
2399        bool            hit_eof = false;
2400        bool            result = false;
2401        char            mblen_str[2];
2402
2403        /* CSV variables */
2404        bool            first_char_in_line = true;
2405        bool            in_quote = false,
2406                                last_was_esc = false;
2407        char            quotec = '\0';
2408        char            escapec = '\0';
2409
2410        if (cstate->csv_mode)
2411        {
2412                quotec = cstate->quote[0];
2413                escapec = cstate->escape[0];
2414                /* ignore special escape processing if it's the same as quotec */
2415                if (quotec == escapec)
2416                        escapec = '\0';
2417        }
2418
2419        mblen_str[1] = '\0';
2420
2421        /*
2422         * The objective of this loop is to transfer the entire next input line
2423         * into line_buf.  Hence, we only care for detecting newlines (\r and/or
2424         * \n) and the end-of-copy marker (\.).
2425         *
2426         * In CSV mode, \r and \n inside a quoted field are just part of the data
2427         * value and are put in line_buf.  We keep just enough state to know if we
2428         * are currently in a quoted field or not.
2429         *
2430         * These four characters, and the CSV escape and quote characters, are
2431         * assumed the same in frontend and backend encodings.
2432         *
2433         * For speed, we try to move data from raw_buf to line_buf in chunks
2434         * rather than one character at a time.  raw_buf_ptr points to the next
2435         * character to examine; any characters from raw_buf_index to raw_buf_ptr
2436         * have been determined to be part of the line, but not yet transferred to
2437         * line_buf.
2438         *
2439         * For a little extra speed within the loop, we copy raw_buf and
2440         * raw_buf_len into local variables.
2441         */
2442        copy_raw_buf = cstate->raw_buf;
2443        raw_buf_ptr = cstate->raw_buf_index;
2444        copy_buf_len = cstate->raw_buf_len;
2445
2446        for (;;)
2447        {
2448                int                     prev_raw_ptr;
2449                char            c;
2450
2451                /*
2452                 * Load more data if needed.  Ideally we would just force four bytes
2453                 * of read-ahead and avoid the many calls to
2454                 * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol
2455                 * does not allow us to read too far ahead or we might read into the
2456                 * next data, so we read-ahead only as far we know we can.      One
2457                 * optimization would be to read-ahead four byte here if
2458                 * cstate->copy_dest != COPY_OLD_FE, but it hardly seems worth it,
2459                 * considering the size of the buffer.
2460                 */
2461                if (raw_buf_ptr >= copy_buf_len || need_data)
2462                {
2463                        REFILL_LINEBUF;
2464
2465                        /*
2466                         * Try to read some more data.  This will certainly reset
2467                         * raw_buf_index to zero, and raw_buf_ptr must go with it.
2468                         */
2469                        if (!CopyLoadRawBuf(cstate))
2470                                hit_eof = true;
2471                        raw_buf_ptr = 0;
2472                        copy_buf_len = cstate->raw_buf_len;
2473
2474                        /*
2475                         * If we are completely out of data, break out of the loop,
2476                         * reporting EOF.
2477                         */
2478                        if (copy_buf_len <= 0)
2479                        {
2480                                result = true;
2481                                break;
2482                        }
2483                        need_data = false;
2484                }
2485
2486                /* OK to fetch a character */
2487                prev_raw_ptr = raw_buf_ptr;
2488                c = copy_raw_buf[raw_buf_ptr++];
2489
2490                if (cstate->csv_mode)
2491                {
2492                        /*
2493                         * If character is '\\' or '\r', we may need to look ahead below.
2494                         * Force fetch of the next character if we don't already have it.
2495                         * We need to do this before changing CSV state, in case one of
2496                         * these characters is also the quote or escape character.
2497                         *
2498                         * Note: old-protocol does not like forced prefetch, but it's OK
2499                         * here since we cannot validly be at EOF.
2500                         */
2501                        if (c == '\\' || c == '\r')
2502                        {
2503                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2504                        }
2505
2506                        /*
2507                         * Dealing with quotes and escapes here is mildly tricky. If the
2508                         * quote char is also the escape char, there's no problem - we
2509                         * just use the char as a toggle. If they are different, we need
2510                         * to ensure that we only take account of an escape inside a
2511                         * quoted field and immediately preceding a quote char, and not
2512                         * the second in a escape-escape sequence.
2513                         */
2514                        if (in_quote && c == escapec)
2515                                last_was_esc = !last_was_esc;
2516                        if (c == quotec && !last_was_esc)
2517                                in_quote = !in_quote;
2518                        if (c != escapec)
2519                                last_was_esc = false;
2520
2521                        /*
2522                         * Updating the line count for embedded CR and/or LF chars is
2523                         * necessarily a little fragile - this test is probably about the
2524                         * best we can do.      (XXX it's arguable whether we should do this
2525                         * at all --- is cur_lineno a physical or logical count?)
2526                         */
2527                        if (in_quote && c == (cstate->eol_type == EOL_NL ? '\n' : '\r'))
2528                                cstate->cur_lineno++;
2529                }
2530
2531                /* Process \r */
2532                if (c == '\r' && (!cstate->csv_mode || !in_quote))
2533                {
2534                        /* Check for \r\n on first line, _and_ handle \r\n. */
2535                        if (cstate->eol_type == EOL_UNKNOWN ||
2536                                cstate->eol_type == EOL_CRNL)
2537                        {
2538                                /*
2539                                 * If need more data, go back to loop top to load it.
2540                                 *
2541                                 * Note that if we are at EOF, c will wind up as '\0' because
2542                                 * of the guaranteed pad of raw_buf.
2543                                 */
2544                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2545
2546                                /* get next char */
2547                                c = copy_raw_buf[raw_buf_ptr];
2548
2549                                if (c == '\n')
2550                                {
2551                                        raw_buf_ptr++;          /* eat newline */
2552                                        cstate->eol_type = EOL_CRNL;            /* in case not set yet */
2553                                }
2554                                else
2555                                {
2556                                        /* found \r, but no \n */
2557                                        if (cstate->eol_type == EOL_CRNL)
2558                                                ereport(ERROR,
2559                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2560                                                                 !cstate->csv_mode ?
2561                                                        errmsg("literal carriage return found in data") :
2562                                                        errmsg("unquoted carriage return found in data"),
2563                                                                 !cstate->csv_mode ?
2564                                                errhint("Use \"\\r\" to represent carriage return.") :
2565                                                                 errhint("Use quoted CSV field to represent carriage return.")));
2566
2567                                        /*
2568                                         * if we got here, it is the first line and we didn't find
2569                                         * \n, so don't consume the peeked character
2570                                         */
2571                                        cstate->eol_type = EOL_CR;
2572                                }
2573                        }
2574                        else if (cstate->eol_type == EOL_NL)
2575                                ereport(ERROR,
2576                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2577                                                 !cstate->csv_mode ?
2578                                                 errmsg("literal carriage return found in data") :
2579                                                 errmsg("unquoted carriage return found in data"),
2580                                                 !cstate->csv_mode ?
2581                                           errhint("Use \"\\r\" to represent carriage return.") :
2582                                                 errhint("Use quoted CSV field to represent carriage return.")));
2583                        /* If reach here, we have found the line terminator */
2584                        break;
2585                }
2586
2587                /* Process \n */
2588                if (c == '\n' && (!cstate->csv_mode || !in_quote))
2589                {
2590                        if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
2591                                ereport(ERROR,
2592                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2593                                                 !cstate->csv_mode ?
2594                                                 errmsg("literal newline found in data") :
2595                                                 errmsg("unquoted newline found in data"),
2596                                                 !cstate->csv_mode ?
2597                                                 errhint("Use \"\\n\" to represent newline.") :
2598                                         errhint("Use quoted CSV field to represent newline.")));
2599                        cstate->eol_type = EOL_NL;      /* in case not set yet */
2600                        /* If reach here, we have found the line terminator */
2601                        break;
2602                }
2603
2604                /*
2605                 * In CSV mode, we only recognize \. alone on a line.  This is because
2606                 * \. is a valid CSV data value.
2607                 */
2608                if (c == '\\' && (!cstate->csv_mode || first_char_in_line))
2609                {
2610                        char            c2;
2611
2612                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2613                        IF_NEED_REFILL_AND_EOF_BREAK(0);
2614
2615                        /* -----
2616                         * get next character
2617                         * Note: we do not change c so if it isn't \., we can fall
2618                         * through and continue processing for client encoding.
2619                         * -----
2620                         */
2621                        c2 = copy_raw_buf[raw_buf_ptr];
2622
2623                        if (c2 == '.')
2624                        {
2625                                raw_buf_ptr++;  /* consume the '.' */
2626
2627                                /*
2628                                 * Note: if we loop back for more data here, it does not
2629                                 * matter that the CSV state change checks are re-executed; we
2630                                 * will come back here with no important state changed.
2631                                 */
2632                                if (cstate->eol_type == EOL_CRNL)
2633                                {
2634                                        /* Get the next character */
2635                                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2636                                        /* if hit_eof, c2 will become '\0' */
2637                                        c2 = copy_raw_buf[raw_buf_ptr++];
2638
2639                                        if (c2 == '\n')
2640                                        {
2641                                                if (!cstate->csv_mode)
2642                                                        ereport(ERROR,
2643                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2644                                                                         errmsg("end-of-copy marker does not match previous newline style")));
2645                                                else
2646                                                        NO_END_OF_COPY_GOTO;
2647                                        }
2648                                        else if (c2 != '\r')
2649                                        {
2650                                                if (!cstate->csv_mode)
2651                                                        ereport(ERROR,
2652                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2653                                                                         errmsg("end-of-copy marker corrupt")));
2654                                                else
2655                                                        NO_END_OF_COPY_GOTO;
2656                                        }
2657                                }
2658
2659                                /* Get the next character */
2660                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2661                                /* if hit_eof, c2 will become '\0' */
2662                                c2 = copy_raw_buf[raw_buf_ptr++];
2663
2664                                if (c2 != '\r' && c2 != '\n')
2665                                {
2666                                        if (!cstate->csv_mode)
2667                                                ereport(ERROR,
2668                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2669                                                                 errmsg("end-of-copy marker corrupt")));
2670                                        else
2671                                                NO_END_OF_COPY_GOTO;
2672                                }
2673
2674                                if ((cstate->eol_type == EOL_NL && c2 != '\n') ||
2675                                        (cstate->eol_type == EOL_CRNL && c2 != '\n') ||
2676                                        (cstate->eol_type == EOL_CR && c2 != '\r'))
2677                                {
2678                                        ereport(ERROR,
2679                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2680                                                         errmsg("end-of-copy marker does not match previous newline style")));
2681                                }
2682
2683                                /*
2684                                 * Transfer only the data before the \. into line_buf, then
2685                                 * discard the data and the \. sequence.
2686                                 */
2687                                if (prev_raw_ptr > cstate->raw_buf_index)
2688                                        appendBinaryStringInfo(&cstate->line_buf,
2689                                                                         cstate->raw_buf + cstate->raw_buf_index,
2690                                                                           prev_raw_ptr - cstate->raw_buf_index);
2691                                cstate->raw_buf_index = raw_buf_ptr;
2692                                result = true;  /* report EOF */
2693                                break;
2694                        }
2695                        else if (!cstate->csv_mode)
2696
2697                                /*
2698                                 * If we are here, it means we found a backslash followed by
2699                                 * something other than a period.  In non-CSV mode, anything
2700                                 * after a backslash is special, so we skip over that second
2701                                 * character too.  If we didn't do that \\. would be
2702                                 * considered an eof-of copy, while in non-CVS mode it is a
2703                                 * literal backslash followed by a period.      In CSV mode,
2704                                 * backslashes are not special, so we want to process the
2705                                 * character after the backslash just like a normal character,
2706                                 * so we don't increment in those cases.
2707                                 */
2708                                raw_buf_ptr++;
2709                }
2710
2711                /*
2712                 * This label is for CSV cases where \. appears at the start of a
2713                 * line, but there is more text after it, meaning it was a data value.
2714                 * We are more strict for \. in CSV mode because \. could be a data
2715                 * value, while in non-CSV mode, \. cannot be a data value.
2716                 */
2717not_end_of_copy:
2718
2719                /*
2720                 * Process all bytes of a multi-byte character as a group.
2721                 *
2722                 * We only support multi-byte sequences where the first byte has the
2723                 * high-bit set, so as an optimization we can avoid this block
2724                 * entirely if it is not set.
2725                 */
2726                if (cstate->encoding_embeds_ascii && IS_HIGHBIT_SET(c))
2727                {
2728                        int                     mblen;
2729
2730                        mblen_str[0] = c;
2731                        /* All our encodings only read the first byte to get the length */
2732                        mblen = pg_encoding_mblen(cstate->client_encoding, mblen_str);
2733                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1);
2734                        IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1);
2735                        raw_buf_ptr += mblen - 1;
2736                }
2737                first_char_in_line = false;
2738        }                                                       /* end of outer loop */
2739
2740        /*
2741         * Transfer any still-uncopied data to line_buf.
2742         */
2743        REFILL_LINEBUF;
2744
2745        return result;
2746}
2747#endif
2748#ifdef BITSTREAM
2749static bool
2750CopyReadLineText(CopyState cstate)
2751{
2752        char       *copy_raw_buf;
2753        int                     raw_buf_ptr;
2754        int                     copy_buf_len;
2755        bool            need_data = false;
2756        bool            hit_eof = false;
2757        bool            result = false;
2758        char            mblen_str[2];
2759
2760        /* CSV variables */
2761        bool            first_char_in_line = true;
2762        char            c,c2;
2763       
2764        mblen_str[1] = '\0';
2765       
2766        copy_raw_buf = cstate->raw_buf;
2767        raw_buf_ptr = cstate->raw_buf_index;
2768        copy_buf_len = cstate->raw_buf_len;
2769
2770        if (cstate->csv_mode){
2771               
2772                if (copy_raw_buf[raw_buf_ptr]=='\\' && copy_raw_buf[raw_buf_ptr+1]=='.'){
2773                        if( copy_raw_buf[raw_buf_ptr+2]=='\n'|| copy_raw_buf[raw_buf_ptr+2]=='\r')
2774                                return 1;
2775                }
2776                while(1){       
2777                        if (raw_buf_ptr >= copy_buf_len)
2778                        {
2779                                raw_buf_ptr = copy_buf_len;
2780                                c = copy_raw_buf[raw_buf_ptr-1];
2781#ifdef BUFFER_PROFILING
2782    start_BOM_interval(copyloadrawbuf_timer);
2783#endif
2784                                if (!CopyLoadRawBuf(cstate))
2785                                        cstate->fe_eof = true;
2786#ifdef BUFFER_PROFILING
2787    if (!cstate->fe_eof) end_BOM_interval(copyloadrawbuf_timer);
2788#endif
2789#ifdef BUFFER_PROFILING
2790    start_BOM_interval(bitstreamgen_timer);
2791#endif                                 
2792
2793                                if(cstate->quote[0]==cstate->escape[0])
2794                                        direct_bitstream_gen(cstate);
2795                                else 
2796                                        direct_bitstream_gen_with_escape(cstate);
2797                                       
2798#ifdef BUFFER_PROFILING
2799    if (!cstate->fe_eof) end_BOM_interval(bitstreamgen_timer);
2800#endif
2801                                raw_buf_ptr = 0;
2802                                copy_buf_len = cstate->raw_buf_len;     
2803                        }
2804                        if(bitblock_has_bit(cstate->EOL_stream[raw_buf_ptr/BLOCK_SIZE_BITS])){
2805                                break;
2806                        }
2807                        else {
2808                                raw_buf_ptr = (raw_buf_ptr/BLOCK_SIZE_BITS+1)*BLOCK_SIZE_BITS;
2809                                if(cstate->fe_eof==1 && raw_buf_ptr > copy_buf_len)
2810                                        return true;
2811                        }
2812                }
2813                int stream_index = raw_buf_ptr/BLOCK_SIZE_BITS;
2814                raw_buf_ptr = stream_index*BLOCK_SIZE_BITS + count_forward_zeroes(cstate->EOL_stream[stream_index]);
2815                cstate->EOL_stream[stream_index] = simd_and(cstate->EOL_stream[stream_index],simd_sll_128(simd_const_1(1),sisd_from_int(raw_buf_ptr%BLOCK_SIZE_BITS+1)));
2816               
2817                if(raw_buf_ptr!=0){
2818                        c = copy_raw_buf[raw_buf_ptr-1];
2819                        c2 = copy_raw_buf[raw_buf_ptr];
2820                }
2821                else{
2822                        c2 = copy_raw_buf[0];
2823                }
2824               
2825                if(c=='\r'){
2826                        if(c2=='\n')
2827                                if(cstate->eol_type == EOL_UNKNOWN ||cstate->eol_type == EOL_CRNL){
2828                                        cstate->eol_type = EOL_CRNL;   
2829                                        raw_buf_ptr++;
2830                                }
2831                                else
2832                                        ereport(ERROR,
2833                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2834                                                         errmsg("unquoted carriage return found in data"),
2835                                                         errhint("Use quoted CSV field to represent newline.")));
2836                        else if(cstate->eol_type == EOL_UNKNOWN ||cstate->eol_type == EOL_CR)
2837                                        cstate->eol_type = EOL_CR;
2838                                else
2839                                        ereport(ERROR,
2840                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2841                                                         errmsg("unquoted carriage return found in data"),
2842                                                         errhint("Use quoted CSV field to represent newline.")));
2843                }
2844                else if(c2=='\n')
2845                        if(cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
2846                                ereport(ERROR,
2847                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2848                                                 errmsg("unquoted newline found in data"),
2849                                                 errhint("Use quoted CSV field to represent newline.")));
2850                        else{
2851                                cstate->eol_type = EOL_NL;     
2852                                raw_buf_ptr++;
2853                        }
2854               
2855        }
2856        else
2857        {
2858                for (;;)
2859                {
2860                        int                     prev_raw_ptr;
2861                        /*
2862                         * Load more data if needed.  Ideally we would just force four bytes
2863                         * of read-ahead and avoid the many calls to
2864                         * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol
2865                         * does not allow us to read too far ahead or we might read into the
2866                         * next data, so we read-ahead only as far we know we can.      One
2867                         * optimization would be to read-ahead four byte here if
2868                         * cstate->copy_dest != COPY_OLD_FE, but it hardly seems worth it,
2869                         * considering the size of the buffer.
2870                         */
2871                        if (raw_buf_ptr >= copy_buf_len || need_data)
2872                        {
2873                                REFILL_LINEBUF;
2874       
2875                                /*
2876                                 * Try to read some more data.  This will certainly reset
2877                                 * raw_buf_index to zero, and raw_buf_ptr must go with it.
2878                                 */
2879                                if (!CopyLoadRawBuf(cstate))
2880                                        hit_eof = true;
2881                                raw_buf_ptr = 0;
2882                                copy_buf_len = cstate->raw_buf_len;
2883       
2884                                /*
2885                                 * If we are completely out of data, break out of the loop,
2886                                 * reporting EOF.
2887                                 */
2888                                if (copy_buf_len <= 0)
2889                                {
2890                                        result = true;
2891                                        break;
2892                                }
2893                                need_data = false;
2894                        }
2895       
2896                        /* OK to fetch a character */
2897                        prev_raw_ptr = raw_buf_ptr;
2898                        c = copy_raw_buf[raw_buf_ptr++];
2899                       
2900                        /* Process \r */
2901                        if (c == '\r' )
2902                        {
2903                                /* Check for \r\n on first line, _and_ handle \r\n. */
2904                                if (cstate->eol_type == EOL_UNKNOWN ||
2905                                        cstate->eol_type == EOL_CRNL)
2906                                {
2907                                        /*
2908                                         * If need more data, go back to loop top to load it.
2909                                         *
2910                                         * Note that if we are at EOF, c will wind up as '\0' because
2911                                         * of the guaranteed pad of raw_buf.
2912                                         */
2913                                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2914       
2915                                        /* get next char */
2916                                        c = copy_raw_buf[raw_buf_ptr];
2917       
2918                                        if (c == '\n')
2919                                        {
2920                                                raw_buf_ptr++;          /* eat newline */
2921                                                cstate->eol_type = EOL_CRNL;            /* in case not set yet */
2922                                        }
2923                                        else
2924                                        {
2925                                                /* found \r, but no \n */
2926                                                if (cstate->eol_type == EOL_CRNL)
2927                                                        ereport(ERROR,
2928                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2929                                                                        errmsg("literal carriage return found in data") ,
2930                                                                        errhint("Use \"\\r\" to represent carriage return.") ));
2931       
2932                                                /*
2933                                                 * if we got here, it is the first line and we didn't find
2934                                                 * \n, so don't consume the peeked character
2935                                                 */
2936                                                cstate->eol_type = EOL_CR;
2937                                        }
2938                                }
2939                                else if (cstate->eol_type == EOL_NL)
2940                                        ereport(ERROR,
2941                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2942                                                         errmsg("literal carriage return found in data"),
2943                                                         errhint("Use \"\\r\" to represent carriage return.")));
2944                                /* If reach here, we have found the line terminator */
2945                                break;
2946                        }
2947       
2948                        /* Process \n */
2949                        if (c == '\n')
2950                        {
2951                                if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
2952                                        ereport(ERROR,
2953                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
2954                                                         errmsg("literal newline found in data") ,
2955                                                         errhint("Use \"\\n\" to represent newline.")));
2956                                cstate->eol_type = EOL_NL;      /* in case not set yet */
2957                                /* If reach here, we have found the line terminator */
2958                                break;
2959                        }
2960       
2961                        /*
2962                         * In CSV mode, we only recognize \. alone on a line.  This is because
2963                         * \. is a valid CSV data value.
2964                         */
2965                        if (c == '\\')
2966                        {
2967                                char            c2;
2968       
2969                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2970                                IF_NEED_REFILL_AND_EOF_BREAK(0);
2971       
2972                                /* -----
2973                                 * get next character
2974                                 * Note: we do not change c so if it isn't \., we can fall
2975                                 * through and continue processing for client encoding.
2976                                 * -----
2977                                 */
2978                                c2 = copy_raw_buf[raw_buf_ptr];
2979       
2980                                if (c2 == '.')
2981                                {
2982                                        raw_buf_ptr++;  /* consume the '.' */
2983       
2984                                        /*
2985                                         * Note: if we loop back for more data here, it does not
2986                                         * matter that the CSV state change checks are re-executed; we
2987                                         * will come back here with no important state changed.
2988                                         */
2989                                        if (cstate->eol_type == EOL_CRNL)
2990                                        {
2991                                                /* Get the next character */
2992                                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
2993                                                /* if hit_eof, c2 will become '\0' */
2994                                                c2 = copy_raw_buf[raw_buf_ptr++];
2995       
2996                                                if (c2 == '\n')
2997                                                {
2998                                                        ereport(ERROR,
2999                                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3000                                                                                 errmsg("end-of-copy marker does not match previous newline style")));
3001                                                }
3002                                                else if (c2 != '\r')
3003                                                {
3004                                                        ereport(ERROR,
3005                                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3006                                                                                 errmsg("end-of-copy marker corrupt")));
3007                                                }
3008                                        }
3009       
3010                                        /* Get the next character */
3011                                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
3012                                        /* if hit_eof, c2 will become '\0' */
3013                                        c2 = copy_raw_buf[raw_buf_ptr++];
3014       
3015                                        if (c2 != '\r' && c2 != '\n')
3016                                        {
3017                                                ereport(ERROR,
3018                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3019                                                                         errmsg("end-of-copy marker corrupt")));
3020                                        }
3021       
3022                                        if ((cstate->eol_type == EOL_NL && c2 != '\n') ||
3023                                                (cstate->eol_type == EOL_CRNL && c2 != '\n') ||
3024                                                (cstate->eol_type == EOL_CR && c2 != '\r'))
3025                                        {
3026                                                ereport(ERROR,
3027                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3028                                                                 errmsg("end-of-copy marker does not match previous newline style")));
3029                                        }
3030       
3031                                        /*
3032                                         * Transfer only the data before the \. into line_buf, then
3033                                         * discard the data and the \. sequence.
3034                                         */
3035                                        if (prev_raw_ptr > cstate->raw_buf_index)
3036                                                appendBinaryStringInfo(&cstate->line_buf,
3037                                                                                 cstate->raw_buf + cstate->raw_buf_index,
3038                                                                                   prev_raw_ptr - cstate->raw_buf_index);
3039                                        cstate->raw_buf_index = raw_buf_ptr;
3040                                        result = true;  /* report EOF */
3041                                        break;
3042                                }
3043                                else 
3044       
3045                                        /*
3046                                         * If we are here, it means we found a backslash followed by
3047                                         * something other than a period.  In non-CSV mode, anything
3048                                         * after a backslash is special, so we skip over that second
3049                                         * character too.  If we didn't do that \\. would be
3050                                         * considered an eof-of copy, while in non-CVS mode it is a
3051                                         * literal backslash followed by a period.      In CSV mode,
3052                                         * backslashes are not special, so we want to process the
3053                                         * character after the backslash just like a normal character,
3054                                         * so we don't increment in those cases.
3055                                         */
3056                                        raw_buf_ptr++;
3057                        }
3058
3059                        /*
3060                         * This label is for CSV cases where \. appears at the start of a
3061                         * line, but there is more text after it, meaning it was a data value.
3062                         * We are more strict for \. in CSV mode because \. could be a data
3063                         * value, while in non-CSV mode, \. cannot be a data value.
3064                         */
3065        not_end_of_copy:
3066       
3067                        /*
3068                         * Process all bytes of a multi-byte character as a group.
3069                         *
3070                         * We only support multi-byte sequences where the first byte has the
3071                         * high-bit set, so as an optimization we can avoid this block
3072                         * entirely if it is not set.
3073                         */
3074                        if (cstate->encoding_embeds_ascii && IS_HIGHBIT_SET(c))
3075                        {
3076                                int                     mblen;
3077       
3078                                mblen_str[0] = c;
3079                                /* All our encodings only read the first byte to get the length */
3080                                mblen = pg_encoding_mblen(cstate->client_encoding, mblen_str);
3081                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1);
3082                                IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1);
3083                                raw_buf_ptr += mblen - 1;
3084                        }
3085                        first_char_in_line = false;
3086               
3087                }       /* end of outer loop */
3088        }                                               
3089
3090        /*
3091         * Transfer any still-uncopied data to line_buf.
3092         */
3093        REFILL_LINEBUF;
3094
3095        return result;
3096}
3097#endif
3098/*
3099 *      Return decimal value for a hexadecimal digit
3100 */
3101static int
3102GetDecimalFromHex(char hex)
3103{
3104        if (isdigit((unsigned char) hex))
3105                return hex - '0';
3106        else
3107                return tolower((unsigned char) hex) - 'a' + 10;
3108}
3109
3110/*
3111 * Parse the current line into separate attributes (fields),
3112 * performing de-escaping as needed.
3113 *
3114 * The input is in line_buf.  We use attribute_buf to hold the result
3115 * strings.  fieldvals[k] is set to point to the k'th attribute string,
3116 * or NULL when the input matches the null marker string.  (Note that the
3117 * caller cannot check for nulls since the returned string would be the
3118 * post-de-escaping equivalent, which may look the same as some valid data
3119 * string.)
3120 *
3121 * delim is the column delimiter string (must be just one byte for now).
3122 * null_print is the null marker string.  Note that this is compared to
3123 * the pre-de-escaped input string.
3124 *
3125 * The return value is the number of fields actually read.      (We error out
3126 * if this would exceed maxfields, which is the length of fieldvals[].)
3127 */
3128static int
3129CopyReadAttributesText(CopyState cstate, int maxfields, char **fieldvals)
3130{
3131        char            delimc = cstate->delim[0];
3132        int                     fieldno;
3133        char       *output_ptr;
3134        char       *cur_ptr;
3135        char       *line_end_ptr;
3136
3137        /*
3138         * We need a special case for zero-column tables: check that the input
3139         * line is empty, and return.
3140         */
3141        if (maxfields <= 0)
3142        {
3143                if (cstate->line_buf.len != 0)
3144                        ereport(ERROR,
3145                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3146                                         errmsg("extra data after last expected column")));
3147                return 0;
3148        }
3149
3150        resetStringInfo(&cstate->attribute_buf);
3151
3152        /*
3153         * The de-escaped attributes will certainly not be longer than the input
3154         * data line, so we can just force attribute_buf to be large enough and
3155         * then transfer data without any checks for enough space.      We need to do
3156         * it this way because enlarging attribute_buf mid-stream would invalidate
3157         * pointers already stored into fieldvals[].
3158         */
3159        if (cstate->attribute_buf.maxlen <= cstate->line_buf.len)
3160                enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len);
3161        output_ptr = cstate->attribute_buf.data;
3162
3163        /* set pointer variables for loop */
3164        cur_ptr = cstate->line_buf.data;
3165        line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
3166
3167        /* Outer loop iterates over fields */
3168        fieldno = 0;
3169        for (;;)
3170        {
3171                bool            found_delim = false;
3172                char       *start_ptr;
3173                char       *end_ptr;
3174                int                     input_len;
3175                bool            saw_non_ascii = false;
3176
3177                /* Make sure space remains in fieldvals[] */
3178                if (fieldno >= maxfields)
3179                        ereport(ERROR,
3180                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3181                                         errmsg("extra data after last expected column")));
3182
3183                /* Remember start of field on both input and output sides */
3184                start_ptr = cur_ptr;
3185                fieldvals[fieldno] = output_ptr;
3186
3187                /* Scan data for field */
3188                for (;;)
3189                {
3190                        char            c;
3191
3192                        end_ptr = cur_ptr;
3193                        if (cur_ptr >= line_end_ptr)
3194                                break;
3195                        c = *cur_ptr++;
3196                        if (c == delimc)
3197                        {
3198                                found_delim = true;
3199                                break;
3200                        }
3201                        if (c == '\\')
3202                        {
3203                                if (cur_ptr >= line_end_ptr)
3204                                        break;
3205                                c = *cur_ptr++;
3206                                switch (c)
3207                                {
3208                                        case '0':
3209                                        case '1':
3210                                        case '2':
3211                                        case '3':
3212                                        case '4':
3213                                        case '5':
3214                                        case '6':
3215                                        case '7':
3216                                                {
3217                                                        /* handle \013 */
3218                                                        int                     val;
3219
3220                                                        val = OCTVALUE(c);
3221                                                        if (cur_ptr < line_end_ptr)
3222                                                        {
3223                                                                c = *cur_ptr;
3224                                                                if (ISOCTAL(c))
3225                                                                {
3226                                                                        cur_ptr++;
3227                                                                        val = (val << 3) + OCTVALUE(c);
3228                                                                        if (cur_ptr < line_end_ptr)
3229                                                                        {
3230                                                                                c = *cur_ptr;
3231                                                                                if (ISOCTAL(c))
3232                                                                                {
3233                                                                                        cur_ptr++;
3234                                                                                        val = (val << 3) + OCTVALUE(c);
3235                                                                                }
3236                                                                        }
3237                                                                }
3238                                                        }
3239                                                        c = val & 0377;
3240                                                        if (c == '\0' || IS_HIGHBIT_SET(c))
3241                                                                saw_non_ascii = true;
3242                                                }
3243                                                break;
3244                                        case 'x':
3245                                                /* Handle \x3F */
3246                                                if (cur_ptr < line_end_ptr)
3247                                                {
3248                                                        char            hexchar = *cur_ptr;
3249
3250                                                        if (isxdigit((unsigned char) hexchar))
3251                                                        {
3252                                                                int                     val = GetDecimalFromHex(hexchar);
3253
3254                                                                cur_ptr++;
3255                                                                if (cur_ptr < line_end_ptr)
3256                                                                {
3257                                                                        hexchar = *cur_ptr;
3258                                                                        if (isxdigit((unsigned char) hexchar))
3259                                                                        {
3260                                                                                cur_ptr++;
3261                                                                                val = (val << 4) + GetDecimalFromHex(hexchar);
3262                                                                        }
3263                                                                }
3264                                                                c = val & 0xff;
3265                                                                if (c == '\0' || IS_HIGHBIT_SET(c))
3266                                                                        saw_non_ascii = true;
3267                                                        }
3268                                                }
3269                                                break;
3270                                        case 'b':
3271                                                c = '\b';
3272                                                break;
3273                                        case 'f':
3274                                                c = '\f';
3275                                                break;
3276                                        case 'n':
3277                                                c = '\n';
3278                                                break;
3279                                        case 'r':
3280                                                c = '\r';
3281                                                break;
3282                                        case 't':
3283                                                c = '\t';
3284                                                break;
3285                                        case 'v':
3286                                                c = '\v';
3287                                                break;
3288
3289                                                /*
3290                                                 * in all other cases, take the char after '\'
3291                                                 * literally
3292                                                 */
3293                                }
3294                        }
3295
3296                        /* Add c to output string */
3297                        *output_ptr++ = c;
3298                }
3299
3300                /* Terminate attribute value in output area */
3301                *output_ptr++ = '\0';
3302
3303                /*
3304                 * If we de-escaped a non-7-bit-ASCII char, make sure we still have
3305                 * valid data for the db encoding. Avoid calling strlen here for the
3306                 * sake of efficiency.
3307                 */
3308                if (saw_non_ascii)
3309                {
3310                        char       *fld = fieldvals[fieldno];
3311
3312                        pg_verifymbstr(fld, output_ptr - (fld + 1), false);
3313                }
3314
3315                /* Check whether raw input matched null marker */
3316                input_len = end_ptr - start_ptr;
3317                if (input_len == cstate->null_print_len &&
3318                        strncmp(start_ptr, cstate->null_print, input_len) == 0)
3319                        fieldvals[fieldno] = NULL;
3320
3321                fieldno++;
3322                /* Done if we hit EOL instead of a delim */
3323                if (!found_delim)
3324                        break;
3325        }
3326
3327        /* Clean up state of attribute_buf */
3328        output_ptr--;
3329        Assert(*output_ptr == '\0');
3330        cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data);
3331
3332        return fieldno;
3333}
3334
3335/*
3336 * Parse the current line into separate attributes (fields),
3337 * performing de-escaping as needed.  This has exactly the same API as
3338 * CopyReadAttributesText, except we parse the fields according to
3339 * "standard" (i.e. common) CSV usage.
3340 */
3341
3342#ifndef BITSTREAM
3343static int
3344CopyReadAttributesCSV(CopyState cstate, int maxfields, char **fieldvals)
3345{
3346        char            delimc = cstate->delim[0];
3347        char            quotec = cstate->quote[0];
3348        char            escapec = cstate->escape[0];
3349        int                     fieldno;
3350        char       *output_ptr;
3351        char       *cur_ptr;
3352        char       *line_end_ptr;
3353
3354        /*
3355         * We need a special case for zero-column tables: check that the input
3356         * line is empty, and return.
3357         */
3358        if (maxfields <= 0)
3359        {
3360                if (cstate->line_buf.len != 0)
3361                        ereport(ERROR,
3362                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3363                                         errmsg("extra data after last expected column")));
3364                return 0;
3365        }
3366
3367        resetStringInfo(&cstate->attribute_buf);
3368
3369        /*
3370         * The de-escaped attributes will certainly not be longer than the input
3371         * data line, so we can just force attribute_buf to be large enough and
3372         * then transfer data without any checks for enough space.      We need to do
3373         * it this way because enlarging attribute_buf mid-stream would invalidate
3374         * pointers already stored into fieldvals[].
3375         */
3376        if (cstate->attribute_buf.maxlen <= cstate->line_buf.len)
3377                enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len);
3378        output_ptr = cstate->attribute_buf.data;
3379
3380        /* set pointer variables for loop */
3381        cur_ptr = cstate->line_buf.data;
3382        line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
3383
3384        /* Outer loop iterates over fields */
3385        fieldno = 0;
3386        for (;;)
3387        {
3388                bool            found_delim = false;
3389                bool            saw_quote = false;
3390                char       *start_ptr;
3391                char       *end_ptr;
3392                int                     input_len;
3393
3394                /* Make sure space remains in fieldvals[] */
3395                if (fieldno >= maxfields)
3396                        ereport(ERROR,
3397                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3398                                         errmsg("extra data after last expected column")));
3399
3400                /* Remember start of field on both input and output sides */
3401                start_ptr = cur_ptr;
3402                fieldvals[fieldno] = output_ptr;
3403
3404                /*
3405                 * Scan data for field,
3406                 *
3407                 * The loop starts in "not quote" mode and then toggles between that
3408                 * and "in quote" mode. The loop exits normally if it is in "not
3409                 * quote" mode and a delimiter or line end is seen.
3410                 */
3411                for (;;)
3412                {
3413                        char            c;
3414
3415                        /* Not in quote */
3416                        for (;;)
3417                        {
3418                                end_ptr = cur_ptr;
3419                                if (cur_ptr >= line_end_ptr)
3420                                        goto endfield;
3421                                c = *cur_ptr++;
3422                                /* unquoted field delimiter */
3423                                if (c == delimc)
3424                                {
3425                                        found_delim = true;
3426                                        goto endfield;
3427                                }
3428                                /* start of quoted field (or part of field) */
3429                                if (c == quotec)
3430                                {
3431                                        saw_quote = true;
3432                                        break;
3433                                }
3434                                /* Add c to output string */
3435                                *output_ptr++ = c;
3436                        }
3437
3438                        /* In quote */
3439                        for (;;)
3440                        {
3441                                end_ptr = cur_ptr;
3442                                if (cur_ptr >= line_end_ptr)
3443                                        ereport(ERROR,
3444                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3445                                                         errmsg("unterminated CSV quoted field")));
3446
3447                                c = *cur_ptr++;
3448
3449                                /* escape within a quoted field */
3450                                if (c == escapec)
3451                                {
3452                                        /*
3453                                         * peek at the next char if available, and escape it if it
3454                                         * is an escape char or a quote char
3455                                         */
3456                                        if (cur_ptr < line_end_ptr)
3457                                        {
3458                                                char            nextc = *cur_ptr;
3459
3460                                                if (nextc == escapec || nextc == quotec)
3461                                                {
3462                                                        *output_ptr++ = nextc;
3463                                                        cur_ptr++;
3464                                                        continue;
3465                                                }
3466                                        }
3467                                }
3468
3469                                /*
3470                                 * end of quoted field. Must do this test after testing for
3471                                 * escape in case quote char and escape char are the same
3472                                 * (which is the common case).
3473                                 */
3474                                if (c == quotec)
3475                                        break;
3476
3477                                /* Add c to output string */
3478                                *output_ptr++ = c;
3479                        }
3480                }
3481endfield:
3482
3483                /* Terminate attribute value in output area */
3484                *output_ptr++ = '\0';
3485
3486                /* Check whether raw input matched null marker */
3487                input_len = end_ptr - start_ptr;
3488                if (!saw_quote && input_len == cstate->null_print_len &&
3489                        strncmp(start_ptr, cstate->null_print, input_len) == 0)
3490                        fieldvals[fieldno] = NULL;
3491
3492                fieldno++;
3493                /* Done if we hit EOL instead of a delim */
3494                if (!found_delim)
3495                        break;
3496        }
3497
3498        /* Clean up state of attribute_buf */
3499        output_ptr--;
3500        Assert(*output_ptr == '\0');
3501        cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data);
3502
3503        return fieldno;
3504}
3505#endif
3506
3507#ifdef BITSTREAM
3508static int
3509CopyReadAttributesCSV(CopyState cstate, int maxfields, char **fieldvals)
3510{
3511        char            delimc = cstate->delim[0];
3512        char            quotec = cstate->quote[0];
3513        char            escapec = cstate->escape[0];
3514        int                     fieldno;
3515        char       *output_ptr;
3516        char       *cur_ptr;
3517        char       *line_end_ptr;
3518
3519        /*
3520         * We need a special case for zero-column tables: check that the input
3521         * line is empty, and return.
3522         */
3523        if (maxfields <= 0)
3524        {
3525                if (cstate->line_buf.len != 0)
3526                        ereport(ERROR,
3527                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3528                                         errmsg("extra data after last expected column")));
3529                return 0;
3530        }
3531
3532        resetStringInfo(&cstate->attribute_buf);
3533
3534        /*
3535         * The de-escaped attributes will certainly not be longer than the input
3536         * data line, so we can just force attribute_buf to be large enough and
3537         * then transfer data without any checks for enough space.      We need to do
3538         * it this way because enlarging attribute_buf mid-stream would invalidate
3539         * pointers already stored into fieldvals[].
3540         */
3541        if (cstate->attribute_buf.maxlen <= cstate->line_buf.len)
3542                enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len);
3543        output_ptr = cstate->attribute_buf.data;
3544
3545        /* set pointer variables for loop */
3546        cur_ptr = cstate->line_buf.data;
3547        line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
3548
3549        /* Outer loop iterates over fields */
3550        fieldno = 0;
3551        for (;;)
3552        {
3553                bool            found_delim = false;
3554                bool            saw_quote = false;
3555                char       *start_ptr;
3556                char       *end_ptr;
3557                int                     input_len;
3558
3559                /* Make sure space remains in fieldvals[] */
3560                if (fieldno >= maxfields)
3561                        ereport(ERROR,
3562                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3563                                         errmsg("extra data after last expected column")));
3564
3565                /* Remember start of field on both input and output sides */
3566                start_ptr = cur_ptr;
3567                fieldvals[fieldno] = output_ptr;
3568
3569                /*
3570                 * Scan data for field,
3571                 *
3572                 * The loop starts in "not quote" mode and then toggles between that
3573                 * and "in quote" mode. The loop exits normally if it is in "not
3574                 * quote" mode and a delimiter or line end is seen.
3575                 */
3576                for (;;)
3577                {
3578                        char            c;
3579
3580                        /* Not in quote */
3581                        for (;;)
3582                        {
3583                                end_ptr = cur_ptr;
3584                                if (cur_ptr >= line_end_ptr)
3585                                        goto endfield;
3586                                c = *cur_ptr++;
3587                                /* unquoted field delimiter */
3588                                if (c == delimc)
3589                                {
3590                                        found_delim = true;
3591                                        goto endfield;
3592                                }
3593                                /* start of quoted field (or part of field) */
3594                                if (c == quotec)
3595                                {
3596                                        saw_quote = true;
3597                                        break;
3598                                }
3599                                /* Add c to output string */
3600                                *output_ptr++ = c;
3601                        }
3602
3603                        /* In quote */
3604                        for (;;)
3605                        {
3606                                end_ptr = cur_ptr;
3607                                if (cur_ptr >= line_end_ptr)
3608                                        ereport(ERROR,
3609                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3610                                                         errmsg("unterminated CSV quoted field")));
3611
3612                                c = *cur_ptr++;
3613
3614                                /* escape within a quoted field */
3615                                if (c == escapec)
3616                                {
3617                                        /*
3618                                         * peek at the next char if available, and escape it if it
3619                                         * is an escape char or a quote char
3620                                         */
3621                                        if (cur_ptr < line_end_ptr)
3622                                        {
3623                                                char            nextc = *cur_ptr;
3624
3625                                                if (nextc == escapec || nextc == quotec)
3626                                                {
3627                                                        *output_ptr++ = nextc;
3628                                                        cur_ptr++;
3629                                                        continue;
3630                                                }
3631                                        }
3632                                }
3633
3634                                /*
3635                                 * end of quoted field. Must do this test after testing for
3636                                 * escape in case quote char and escape char are the same
3637                                 * (which is the common case).
3638                                 */
3639                                if (c == quotec)
3640                                        break;
3641
3642                                /* Add c to output string */
3643                                *output_ptr++ = c;
3644                        }
3645                }
3646endfield:
3647
3648                /* Terminate attribute value in output area */
3649                *output_ptr++ = '\0';
3650
3651                /* Check whether raw input matched null marker */
3652                input_len = end_ptr - start_ptr;
3653                if (!saw_quote && input_len == cstate->null_print_len &&
3654                        strncmp(start_ptr, cstate->null_print, input_len) == 0)
3655                        fieldvals[fieldno] = NULL;
3656
3657                fieldno++;
3658                /* Done if we hit EOL instead of a delim */
3659                if (!found_delim)
3660                        break;
3661        }
3662
3663        /* Clean up state of attribute_buf */
3664        output_ptr--;
3665        Assert(*output_ptr == '\0');
3666        cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data);
3667
3668        return fieldno;
3669}
3670#endif
3671
3672/*
3673 * Read a binary attribute
3674 */
3675static Datum
3676CopyReadBinaryAttribute(CopyState cstate,
3677                                                int column_no, FmgrInfo *flinfo,
3678                                                Oid typioparam, int32 typmod,
3679                                                bool *isnull)
3680{
3681        int32           fld_size;
3682        Datum           result;
3683
3684        if (!CopyGetInt32(cstate, &fld_size))
3685                ereport(ERROR,
3686                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3687                                 errmsg("unexpected EOF in COPY data")));
3688        if (fld_size == -1)
3689        {
3690                *isnull = true;
3691                return ReceiveFunctionCall(flinfo, NULL, typioparam, typmod);
3692        }
3693        if (fld_size < 0)
3694                ereport(ERROR,
3695                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3696                                 errmsg("invalid field size")));
3697
3698        /* reset attribute_buf to empty, and load raw data in it */
3699        resetStringInfo(&cstate->attribute_buf);
3700
3701        enlargeStringInfo(&cstate->attribute_buf, fld_size);
3702        if (CopyGetData(cstate, cstate->attribute_buf.data,
3703                                        fld_size, fld_size) != fld_size)
3704                ereport(ERROR,
3705                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3706                                 errmsg("unexpected EOF in COPY data")));
3707
3708        cstate->attribute_buf.len = fld_size;
3709        cstate->attribute_buf.data[fld_size] = '\0';
3710
3711        /* Call the column type's binary input converter */
3712        result = ReceiveFunctionCall(flinfo, &cstate->attribute_buf,
3713                                                                 typioparam, typmod);
3714
3715        /* Trouble if it didn't eat the whole buffer */
3716        if (cstate->attribute_buf.cursor != cstate->attribute_buf.len)
3717                ereport(ERROR,
3718                                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
3719                                 errmsg("incorrect binary data format")));
3720
3721        *isnull = false;
3722        return result;
3723}
3724
3725/*
3726 * Send text representation of one attribute, with conversion and escaping
3727 */
3728#define DUMPSOFAR() \
3729        do { \
3730                if (ptr > start) \
3731                        CopySendData(cstate, start, ptr - start); \
3732        } while (0)
3733
3734static void
3735CopyAttributeOutText(CopyState cstate, char *string)
3736{
3737        char       *ptr;
3738        char       *start;
3739        char            c;
3740        char            delimc = cstate->delim[0];
3741
3742        if (cstate->need_transcoding)
3743                ptr = pg_server_to_client(string, strlen(string));
3744        else
3745                ptr = string;
3746
3747        /*
3748         * We have to grovel through the string searching for control characters
3749         * and instances of the delimiter character.  In most cases, though, these
3750         * are infrequent.      To avoid overhead from calling CopySendData once per
3751         * character, we dump out all characters between escaped characters in a
3752         * single call.  The loop invariant is that the data from "start" to "ptr"
3753         * can be sent literally, but hasn't yet been.
3754         *
3755         * We can skip pg_encoding_mblen() overhead when encoding is safe, because
3756         * in valid backend encodings, extra bytes of a multibyte character never
3757         * look like ASCII.  This loop is sufficiently performance-critical that
3758         * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
3759         * of the normal safe-encoding path.
3760         */
3761        if (cstate->encoding_embeds_ascii)
3762        {
3763                start = ptr;
3764                while ((c = *ptr) != '\0')
3765                {
3766                        if ((unsigned char) c < (unsigned char) 0x20)
3767                        {
3768                                /*
3769                                 * \r and \n must be escaped, the others are traditional. We
3770                                 * prefer to dump these using the C-like notation, rather than
3771                                 * a backslash and the literal character, because it makes the
3772                                 * dump file a bit more proof against Microsoftish data
3773                                 * mangling.
3774                                 */
3775                                switch (c)
3776                                {
3777                                        case '\b':
3778                                                c = 'b';
3779                                                break;
3780                                        case '\f':
3781                                                c = 'f';
3782                                                break;
3783                                        case '\n':
3784                                                c = 'n';
3785                                                break;
3786                                        case '\r':
3787                                                c = 'r';
3788                                                break;
3789                                        case '\t':
3790                                                c = 't';
3791                                                break;
3792                                        case '\v':
3793                                                c = 'v';
3794                                                break;
3795                                        default:
3796                                                /* If it's the delimiter, must backslash it */
3797                                                if (c == delimc)
3798                                                        break;
3799                                                /* All ASCII control chars are length 1 */
3800                                                ptr++;
3801                                                continue;               /* fall to end of loop */
3802                                }
3803                                /* if we get here, we need to convert the control char */
3804                                DUMPSOFAR();
3805                                CopySendChar(cstate, '\\');
3806                                CopySendChar(cstate, c);
3807                                start = ++ptr;  /* do not include char in next run */
3808                        }
3809                        else if (c == '\\' || c == delimc)
3810                        {
3811                                DUMPSOFAR();
3812                                CopySendChar(cstate, '\\');
3813                                start = ptr++;  /* we include char in next run */
3814                        }
3815                        else if (IS_HIGHBIT_SET(c))
3816                                ptr += pg_encoding_mblen(cstate->client_encoding, ptr);
3817                        else
3818                                ptr++;
3819                }
3820        }
3821        else
3822        {
3823                start = ptr;
3824                while ((c = *ptr) != '\0')
3825                {
3826                        if ((unsigned char) c < (unsigned char) 0x20)
3827                        {
3828                                /*
3829                                 * \r and \n must be escaped, the others are traditional. We
3830                                 * prefer to dump these using the C-like notation, rather than
3831                                 * a backslash and the literal character, because it makes the
3832                                 * dump file a bit more proof against Microsoftish data
3833                                 * mangling.
3834                                 */
3835                                switch (c)
3836                                {
3837                                        case '\b':
3838                                                c = 'b';
3839                                                break;
3840                                        case '\f':
3841                                                c = 'f';
3842                                                break;
3843                                        case '\n':
3844                                                c = 'n';
3845                                                break;
3846                                        case '\r':
3847                                                c = 'r';
3848                                                break;
3849                                        case '\t':
3850                                                c = 't';
3851                                                break;
3852                                        case '\v':
3853                                                c = 'v';
3854                                                break;
3855                                        default:
3856                                                /* If it's the delimiter, must backslash it */
3857                                                if (c == delimc)
3858                                                        break;
3859                                                /* All ASCII control chars are length 1 */
3860                                                ptr++;
3861                                                continue;               /* fall to end of loop */
3862                                }
3863                                /* if we get here, we need to convert the control char */
3864                                DUMPSOFAR();
3865                                CopySendChar(cstate, '\\');
3866                                CopySendChar(cstate, c);
3867                                start = ++ptr;  /* do not include char in next run */
3868                        }
3869                        else if (c == '\\' || c == delimc)
3870                        {
3871                                DUMPSOFAR();
3872                                CopySendChar(cstate, '\\');
3873                                start = ptr++;  /* we include char in next run */
3874                        }
3875                        else
3876                                ptr++;
3877                }
3878        }
3879
3880        DUMPSOFAR();
3881}
3882
3883/*
3884 * Send text representation of one attribute, with conversion and
3885 * CSV-style escaping
3886 */
3887static void
3888CopyAttributeOutCSV(CopyState cstate, char *string,
3889                                        bool use_quote, bool single_attr)
3890{
3891        char       *ptr;
3892        char       *start;
3893        char            c;
3894        char            delimc = cstate->delim[0];
3895        char            quotec = cstate->quote[0];
3896        char            escapec = cstate->escape[0];
3897
3898        /* force quoting if it matches null_print (before conversion!) */
3899        if (!use_quote && strcmp(string, cstate->null_print) == 0)
3900                use_quote = true;
3901
3902        if (cstate->need_transcoding)
3903                ptr = pg_server_to_client(string, strlen(string));
3904        else
3905                ptr = string;
3906
3907        /*
3908         * Make a preliminary pass to discover if it needs quoting
3909         */
3910        if (!use_quote)
3911        {
3912                /*
3913                 * Because '\.' can be a data value, quote it if it appears alone on a
3914                 * line so it is not interpreted as the end-of-data marker.
3915                 */
3916                if (single_attr && strcmp(ptr, "\\.") == 0)
3917                        use_quote = true;
3918                else
3919                {
3920                        char       *tptr = ptr;
3921
3922                        while ((c = *tptr) != '\0')
3923                        {
3924                                if (c == delimc || c == quotec || c == '\n' || c == '\r')
3925                                {
3926                                        use_quote = true;
3927                                        break;
3928                                }
3929                                if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
3930                                        tptr += pg_encoding_mblen(cstate->client_encoding, tptr);
3931                                else
3932                                        tptr++;
3933                        }
3934                }
3935        }
3936
3937        if (use_quote)
3938        {
3939                CopySendChar(cstate, quotec);
3940
3941                /*
3942                 * We adopt the same optimization strategy as in CopyAttributeOutText
3943                 */
3944                start = ptr;
3945                while ((c = *ptr) != '\0')
3946                {
3947                        if (c == quotec || c == escapec)
3948                        {
3949                                DUMPSOFAR();
3950                                CopySendChar(cstate, escapec);
3951                                start = ptr;    /* we include char in next run */
3952                        }
3953                        if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
3954                                ptr += pg_encoding_mblen(cstate->client_encoding, ptr);
3955                        else
3956                                ptr++;
3957                }
3958                DUMPSOFAR();
3959
3960                CopySendChar(cstate, quotec);
3961        }
3962        else
3963        {
3964                /* If it doesn't need quoting, we can just dump it as-is */
3965                CopySendString(cstate, ptr);
3966        }
3967}
3968
3969/*
3970 * CopyGetAttnums - build an integer list of attnums to be copied
3971 *
3972 * The input attnamelist is either the user-specified column list,
3973 * or NIL if there was none (in which case we want all the non-dropped
3974 * columns).
3975 *
3976 * rel can be NULL ... it's only used for error reports.
3977 */
3978static List *
3979CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
3980{
3981        List       *attnums = NIL;
3982
3983        if (attnamelist == NIL)
3984        {
3985                /* Generate default column list */
3986                Form_pg_attribute *attr = tupDesc->attrs;
3987                int                     attr_count = tupDesc->natts;
3988                int                     i;
3989
3990                for (i = 0; i < attr_count; i++)
3991                {
3992                        if (attr[i]->attisdropped)
3993                                continue;
3994                        attnums = lappend_int(attnums, i + 1);
3995                }
3996        }
3997        else
3998        {
3999                /* Validate the user-supplied list and extract attnums */
4000                ListCell   *l;
4001
4002                foreach(l, attnamelist)
4003                {
4004                        char       *name = strVal(lfirst(l));
4005                        int                     attnum;
4006                        int                     i;
4007
4008                        /* Lookup column name */
4009                        attnum = InvalidAttrNumber;
4010                        for (i = 0; i < tupDesc->natts; i++)
4011                        {
4012                                if (tupDesc->attrs[i]->attisdropped)
4013                                        continue;
4014                                if (namestrcmp(&(tupDesc->attrs[i]->attname), name) == 0)
4015                                {
4016                                        attnum = tupDesc->attrs[i]->attnum;
4017                                        break;
4018                                }
4019                        }
4020                        if (attnum == InvalidAttrNumber)
4021                        {
4022                                if (rel != NULL)
4023                                        ereport(ERROR,
4024                                                        (errcode(ERRCODE_UNDEFINED_COLUMN),
4025                                        errmsg("column \"%s\" of relation \"%s\" does not exist",
4026                                                   name, RelationGetRelationName(rel))));
4027                                else
4028                                        ereport(ERROR,
4029                                                        (errcode(ERRCODE_UNDEFINED_COLUMN),
4030                                                         errmsg("column \"%s\" does not exist",
4031                                                                        name)));
4032                        }
4033                        /* Check for duplicates */
4034                        if (list_member_int(attnums, attnum))
4035                                ereport(ERROR,
4036                                                (errcode(ERRCODE_DUPLICATE_COLUMN),
4037                                                 errmsg("column \"%s\" specified more than once",
4038                                                                name)));
4039                        attnums = lappend_int(attnums, attnum);
4040                }
4041        }
4042
4043        return attnums;
4044}
4045
4046
4047/*
4048 * copy_dest_startup --- executor startup
4049 */
4050static void
4051copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
4052{
4053        /* no-op */
4054}
4055
4056/*
4057 * copy_dest_receive --- receive one tuple
4058 */
4059static void
4060copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
4061{
4062        DR_copy    *myState = (DR_copy *) self;
4063        CopyState       cstate = myState->cstate;
4064
4065        /* Make sure the tuple is fully deconstructed */
4066        slot_getallattrs(slot);
4067
4068        /* And send the data */
4069        CopyOneRowTo(cstate, InvalidOid, slot->tts_values, slot->tts_isnull);
4070}
4071
4072/*
4073 * copy_dest_shutdown --- executor end
4074 */
4075static void
4076copy_dest_shutdown(DestReceiver *self)
4077{
4078        /* no-op */
4079}
4080
4081/*
4082 * copy_dest_destroy --- release DestReceiver object
4083 */
4084static void
4085copy_dest_destroy(DestReceiver *self)
4086{
4087        pfree(self);
4088}
4089
4090/*
4091 * CreateCopyDestReceiver -- create a suitable DestReceiver object
4092 */
4093DestReceiver *
4094CreateCopyDestReceiver(void)
4095{
4096        DR_copy    *self = (DR_copy *) palloc(sizeof(DR_copy));
4097
4098        self->pub.receiveSlot = copy_dest_receive;
4099        self->pub.rStartup = copy_dest_startup;
4100        self->pub.rShutdown = copy_dest_shutdown;
4101        self->pub.rDestroy = copy_dest_destroy;
4102        self->pub.mydest = DestCopyOut;
4103
4104        self->cstate = NULL;            /* will be set later */
4105
4106        return (DestReceiver *) self;
4107}
Note: See TracBrowser for help on using the repository browser.