PostgreSQL Source Code git master
Loading...
Searching...
No Matches
copyto.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * copyto.c
4 * COPY <table> TO file/program/client
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/commands/copyto.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <ctype.h>
18#include <unistd.h>
19#include <sys/stat.h>
20
21#include "access/table.h"
22#include "access/tableam.h"
23#include "access/tupconvert.h"
24#include "catalog/pg_inherits.h"
25#include "commands/copyapi.h"
26#include "commands/progress.h"
27#include "executor/execdesc.h"
28#include "executor/executor.h"
29#include "executor/tuptable.h"
30#include "funcapi.h"
31#include "libpq/libpq.h"
32#include "libpq/pqformat.h"
33#include "mb/pg_wchar.h"
34#include "miscadmin.h"
35#include "pgstat.h"
36#include "storage/fd.h"
37#include "tcop/tcopprot.h"
38#include "utils/json.h"
39#include "utils/lsyscache.h"
40#include "utils/memutils.h"
41#include "utils/rel.h"
42#include "utils/snapmgr.h"
43#include "utils/wait_event.h"
44
45/*
46 * Represents the different dest cases we need to worry about at
47 * the bottom level
48 */
49typedef enum CopyDest
50{
51 COPY_FILE, /* to file (or a piped program) */
52 COPY_FRONTEND, /* to frontend */
53 COPY_CALLBACK, /* to callback function */
55
56/*
57 * This struct contains all the state variables used throughout a COPY TO
58 * operation.
59 *
60 * Multi-byte encodings: all supported client-side encodings encode multi-byte
61 * characters by having the first byte's high bit set. Subsequent bytes of the
62 * character can have the high bit not set. When scanning data in such an
63 * encoding to look for a match to a single-byte (ie ASCII) character, we must
64 * use the full pg_encoding_mblen() machinery to skip over multibyte
65 * characters, else we might find a false match to a trailing byte. In
66 * supported server encodings, there is no possibility of a false match, and
67 * it's faster to make useless comparisons to trailing bytes than it is to
68 * invoke pg_encoding_mblen() to skip over them. encoding_embeds_ascii is true
69 * when we have to do it the hard way.
70 */
71typedef struct CopyToStateData
72{
73 /* format-specific routines */
75
76 /* low-level state data */
77 CopyDest copy_dest; /* type of copy source/destination */
78 FILE *copy_file; /* used if copy_dest == COPY_FILE */
79 StringInfo fe_msgbuf; /* used for all dests during COPY TO */
80
81 int file_encoding; /* file or remote side's character encoding */
82 bool need_transcoding; /* file encoding diff from server? */
83 bool encoding_embeds_ascii; /* ASCII can be non-first byte? */
84
85 /* parameters from the COPY command */
86 Relation rel; /* relation to copy to */
87 QueryDesc *queryDesc; /* executable query to copy from */
88 List *attnumlist; /* integer list of attnums to copy */
89 char *filename; /* filename, or NULL for STDOUT */
90 bool is_program; /* is 'filename' a program to popen? */
91 bool json_row_delim_needed; /* need delimiter before next row */
92 StringInfo json_buf; /* reusable buffer for JSON output,
93 * initialized in BeginCopyTo */
94 TupleDesc tupDesc; /* Descriptor for JSON output; for a column
95 * list this is a projected descriptor */
96 Datum *json_projvalues; /* pre-allocated projection values, or
97 * NULL */
98 bool *json_projnulls; /* pre-allocated projection nulls, or NULL */
99 copy_data_dest_cb data_dest_cb; /* function for writing data */
100
102 Node *whereClause; /* WHERE condition (or NULL) */
103 List *partitions; /* OID list of partitions to copy data from */
104
105 /*
106 * Working state
107 */
108 MemoryContext copycontext; /* per-copy execution context */
109
110 FmgrInfo *out_functions; /* lookup info for output functions */
111 MemoryContext rowcontext; /* per-row evaluation context */
112 uint64 bytes_processed; /* number of bytes processed so far */
114
115/* DestReceiver for COPY (query) TO */
116typedef struct
117{
118 DestReceiver pub; /* publicly-known function pointers */
119 CopyToState cstate; /* CopyToStateData for the command */
120 uint64 processed; /* # of tuples processed */
121} DR_copy;
122
123/* NOTE: there's a copy of this in copyfromparse.c */
124static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
125
126
127/* non-export function prototypes */
128static void EndCopy(CopyToState cstate);
129static void ClosePipeToProgram(CopyToState cstate);
130static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot);
131static void CopyAttributeOutText(CopyToState cstate, const char *string);
132static void CopyAttributeOutCSV(CopyToState cstate, const char *string,
133 bool use_quote);
134static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel,
135 uint64 *processed);
136
137/* built-in format-specific routines */
138static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc);
139static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo);
140static void CopyToTextOneRow(CopyToState cstate, TupleTableSlot *slot);
141static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot);
142static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot,
143 bool is_csv);
144static void CopyToTextLikeEnd(CopyToState cstate);
145static void CopyToJsonOneRow(CopyToState cstate, TupleTableSlot *slot);
146static void CopyToJsonEnd(CopyToState cstate);
147static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc);
148static void CopyToBinaryOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo);
149static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot);
150static void CopyToBinaryEnd(CopyToState cstate);
151
152/* Low-level communications functions */
153static void SendCopyBegin(CopyToState cstate);
154static void SendCopyEnd(CopyToState cstate);
155static void CopySendData(CopyToState cstate, const void *databuf, int datasize);
156static void CopySendString(CopyToState cstate, const char *str);
157static void CopySendChar(CopyToState cstate, char c);
158static void CopySendEndOfRow(CopyToState cstate);
159static void CopySendTextLikeEndOfRow(CopyToState cstate);
160static void CopySendInt32(CopyToState cstate, int32 val);
161static void CopySendInt16(CopyToState cstate, int16 val);
162
163/*
164 * COPY TO routines for built-in formats.
165 */
166
167/* text format */
170 .CopyToOutFunc = CopyToTextLikeOutFunc,
171 .CopyToOneRow = CopyToTextOneRow,
172 .CopyToEnd = CopyToTextLikeEnd,
173};
174
175/* CSV format */
178 .CopyToOutFunc = CopyToTextLikeOutFunc,
179 .CopyToOneRow = CopyToCSVOneRow,
180 .CopyToEnd = CopyToTextLikeEnd,
181};
182
183/* json format */
186 .CopyToOutFunc = CopyToTextLikeOutFunc,
187 .CopyToOneRow = CopyToJsonOneRow,
188 .CopyToEnd = CopyToJsonEnd,
189};
190
191/* binary format */
194 .CopyToOutFunc = CopyToBinaryOutFunc,
195 .CopyToOneRow = CopyToBinaryOneRow,
196 .CopyToEnd = CopyToBinaryEnd,
197};
198
199/* Return a COPY TO routine for the given options */
200static const CopyToRoutine *
202{
203 if (opts->format == COPY_FORMAT_CSV)
204 return &CopyToRoutineCSV;
205 else if (opts->format == COPY_FORMAT_BINARY)
206 return &CopyToRoutineBinary;
207 else if (opts->format == COPY_FORMAT_JSON)
208 return &CopyToRoutineJson;
209
210 /* default is text */
211 return &CopyToRoutineText;
212}
213
214/* Implementation of the start callback for text, CSV, and json formats */
215static void
217{
218 /*
219 * For non-binary copy, we need to convert null_print to file encoding,
220 * because it will be sent directly with CopySendString.
221 */
222 if (cstate->need_transcoding)
224 cstate->opts.null_print_len,
225 cstate->file_encoding);
226
227 /* if a header has been requested send the line */
228 if (cstate->opts.header_line == COPY_HEADER_TRUE)
229 {
230 ListCell *cur;
231 bool hdr_delim = false;
232
234
235 foreach(cur, cstate->attnumlist)
236 {
237 int attnum = lfirst_int(cur);
238 char *colname;
239
240 if (hdr_delim)
241 CopySendChar(cstate, cstate->opts.delim[0]);
242 hdr_delim = true;
243
244 colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
245
246 if (cstate->opts.format == COPY_FORMAT_CSV)
247 CopyAttributeOutCSV(cstate, colname, false);
248 else
249 CopyAttributeOutText(cstate, colname);
250 }
251
253 }
254
255 /*
256 * If FORCE_ARRAY has been specified, send the opening bracket.
257 */
258 if (cstate->opts.format == COPY_FORMAT_JSON && cstate->opts.force_array)
259 {
260 CopySendChar(cstate, '[');
262 }
263}
264
265/*
266 * Implementation of the outfunc callback for text, CSV, and json formats. Assign
267 * the output function data to the given *finfo.
268 */
269static void
271{
273 bool is_varlena;
274
275 /* Set output function for an attribute */
277 fmgr_info(func_oid, finfo);
278}
279
280/* Implementation of the per-row callback for text format */
281static void
283{
284 CopyToTextLikeOneRow(cstate, slot, false);
285}
286
287/* Implementation of the per-row callback for CSV format */
288static void
290{
291 CopyToTextLikeOneRow(cstate, slot, true);
292}
293
294/*
295 * Workhorse for CopyToTextOneRow() and CopyToCSVOneRow().
296 *
297 * We use pg_attribute_always_inline to reduce function call overhead
298 * and to help compilers to optimize away the 'is_csv' condition.
299 */
302 TupleTableSlot *slot,
303 bool is_csv)
304{
305 bool need_delim = false;
306 FmgrInfo *out_functions = cstate->out_functions;
307
309 {
310 Datum value = slot->tts_values[attnum - 1];
311 bool isnull = slot->tts_isnull[attnum - 1];
312
313 if (need_delim)
314 CopySendChar(cstate, cstate->opts.delim[0]);
315 need_delim = true;
316
317 if (isnull)
318 {
319 CopySendString(cstate, cstate->opts.null_print_client);
320 }
321 else
322 {
323 char *string;
324
325 string = OutputFunctionCall(&out_functions[attnum - 1],
326 value);
327
328 if (is_csv)
329 CopyAttributeOutCSV(cstate, string,
330 cstate->opts.force_quote_flags[attnum - 1]);
331 else
332 CopyAttributeOutText(cstate, string);
333 }
334 }
335
337}
338
339/* Implementation of the end callback for text and CSV formats */
340static void
342{
343 /* Nothing to do here */
344}
345
346/* Implementation of the end callback for json format */
347static void
349{
350 if (cstate->opts.force_array)
351 {
352 CopySendChar(cstate, ']');
354 }
355}
356
357/* Implementation of per-row callback for json format */
358static void
360{
362
363 resetStringInfo(cstate->json_buf);
364
365 if (cstate->json_projvalues != NULL)
366 {
367 /*
368 * Column list case: project selected column values into sequential
369 * positions matching the custom TupleDesc, then form a new tuple.
370 */
372 int i = 0;
373
375 {
376 cstate->json_projvalues[i] = slot->tts_values[attnum - 1];
377 cstate->json_projnulls[i] = slot->tts_isnull[attnum - 1];
378 i++;
379 }
380
381 tup = heap_form_tuple(cstate->tupDesc,
382 cstate->json_projvalues,
383 cstate->json_projnulls);
384
385 /*
386 * heap_form_tuple already stamps the datum-length, type-id, and
387 * type-mod fields on t_data, so we can use it directly as a composite
388 * Datum without the extra pallocmemcpy that heap_copy_tuple_as_datum
389 * would do. Any TOAST pointers in the projected values will be
390 * detoasted by the per-column output functions called from
391 * composite_to_json.
392 */
394 }
395 else
396 {
397 /*
398 * Full table or query without column list. For queries, the slot's
399 * TupleDesc may carry RECORDOID, which is not registered in the type
400 * cache and would cause composite_to_json's lookup_rowtype_tupdesc
401 * call to fail. Build a HeapTuple stamped with the blessed
402 * descriptor so the type can be looked up correctly.
403 */
404 if (!cstate->rel && slot->tts_tupleDescriptor->tdtypeid == RECORDOID)
405 {
407 slot->tts_values,
408 slot->tts_isnull);
409
411 }
412 else
414 }
415
416 composite_to_json(rowdata, cstate->json_buf, false);
417
418 if (cstate->opts.force_array)
419 {
420 if (cstate->json_row_delim_needed)
421 CopySendChar(cstate, ',');
422 else
423 {
424 /* first row needs no delimiter */
425 CopySendChar(cstate, ' ');
426 cstate->json_row_delim_needed = true;
427 }
428 }
429
430 /*
431 * Convert the JSON output to the target encoding if needed. Unlike the
432 * text and CSV paths which convert per-attribute via CopyAttributeOut*,
433 * composite_to_json() emits the whole row as one buffer, so we transcode
434 * it here in a single call before sending.
435 */
436 if (cstate->need_transcoding)
437 {
438 char *converted;
439
441 cstate->json_buf->len,
442 cstate->file_encoding);
444 if (converted != cstate->json_buf->data)
446 }
447 else
448 CopySendData(cstate, cstate->json_buf->data, cstate->json_buf->len);
449
451}
452
453/*
454 * Implementation of the start callback for binary format. Send a header
455 * for a binary copy.
456 */
457static void
459{
460 int32 tmp;
461
462 /* Signature */
463 CopySendData(cstate, BinarySignature, 11);
464 /* Flags field */
465 tmp = 0;
466 CopySendInt32(cstate, tmp);
467 /* No header extension */
468 tmp = 0;
469 CopySendInt32(cstate, tmp);
470}
471
472/*
473 * Implementation of the outfunc callback for binary format. Assign
474 * the binary output function to the given *finfo.
475 */
476static void
478{
480 bool is_varlena;
481
482 /* Set output function for an attribute */
484 fmgr_info(func_oid, finfo);
485}
486
487/* Implementation of the per-row callback for binary format */
488static void
490{
491 FmgrInfo *out_functions = cstate->out_functions;
492
493 /* Binary per-tuple header */
494 CopySendInt16(cstate, list_length(cstate->attnumlist));
495
497 {
498 Datum value = slot->tts_values[attnum - 1];
499 bool isnull = slot->tts_isnull[attnum - 1];
500
501 if (isnull)
502 {
503 CopySendInt32(cstate, -1);
504 }
505 else
506 {
508
509 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
510 value);
514 }
515 }
516
517 CopySendEndOfRow(cstate);
518}
519
520/* Implementation of the end callback for binary format */
521static void
523{
524 /* Generate trailer for a binary copy */
525 CopySendInt16(cstate, -1);
526 /* Need to flush out the trailer */
527 CopySendEndOfRow(cstate);
528}
529
530/*
531 * Send copy start/stop messages for frontend copies. These have changed
532 * in past protocol redesigns.
533 */
534static void
536{
538 int natts = list_length(cstate->attnumlist);
539 int16 format = (cstate->opts.format == COPY_FORMAT_BINARY ? 1 : 0);
540 int i;
541
543 pq_sendbyte(&buf, format); /* overall format */
544 if (cstate->opts.format != COPY_FORMAT_JSON)
545 {
546 pq_sendint16(&buf, natts);
547 for (i = 0; i < natts; i++)
548 pq_sendint16(&buf, format); /* per-column formats */
549 }
550 else
551 {
552 /*
553 * For JSON format, report one text-format column. Each CopyData
554 * message contains one complete JSON object, not individual column
555 * values, so the per-column count is always 1.
556 */
557 pq_sendint16(&buf, 1);
558 pq_sendint16(&buf, 0);
559 }
560
562 cstate->copy_dest = COPY_FRONTEND;
563}
564
565static void
567{
568 /* Shouldn't have any unsent data */
569 Assert(cstate->fe_msgbuf->len == 0);
570 /* Send Copy Done message */
572}
573
574/*----------
575 * CopySendData sends output data to the destination (file or frontend)
576 * CopySendString does the same for null-terminated strings
577 * CopySendChar does the same for single characters
578 * CopySendEndOfRow does the appropriate thing at end of each data row
579 * (data is not actually flushed except by CopySendEndOfRow)
580 *
581 * NB: no data conversion is applied by these functions
582 *----------
583 */
584static void
585CopySendData(CopyToState cstate, const void *databuf, int datasize)
586{
588}
589
590static void
591CopySendString(CopyToState cstate, const char *str)
592{
594}
595
596static void
598{
600}
601
602static void
604{
605 StringInfo fe_msgbuf = cstate->fe_msgbuf;
606
607 switch (cstate->copy_dest)
608 {
609 case COPY_FILE:
611 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
612 cstate->copy_file) != 1 ||
613 ferror(cstate->copy_file))
614 {
615 if (cstate->is_program)
616 {
617 if (errno == EPIPE)
618 {
619 /*
620 * The pipe will be closed automatically on error at
621 * the end of transaction, but we might get a better
622 * error message from the subprocess' exit code than
623 * just "Broken Pipe"
624 */
625 ClosePipeToProgram(cstate);
626
627 /*
628 * If ClosePipeToProgram() didn't throw an error, the
629 * program terminated normally, but closed the pipe
630 * first. Restore errno, and throw an error.
631 */
632 errno = EPIPE;
633 }
636 errmsg("could not write to COPY program: %m")));
637 }
638 else
641 errmsg("could not write to COPY file: %m")));
642 }
644 break;
645 case COPY_FRONTEND:
646 /* Dump the accumulated row as one CopyData message */
647 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
648 break;
649 case COPY_CALLBACK:
650 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
651 break;
652 }
653
654 /* Update the progress */
655 cstate->bytes_processed += fe_msgbuf->len;
657
658 resetStringInfo(fe_msgbuf);
659}
660
661/*
662 * Wrapper function of CopySendEndOfRow for text, CSV, and json formats. Sends the
663 * line termination and do common appropriate things for the end of row.
664 */
665static inline void
667{
668 switch (cstate->copy_dest)
669 {
670 case COPY_FILE:
671 /* Default line termination depends on platform */
672#ifndef WIN32
673 CopySendChar(cstate, '\n');
674#else
675 CopySendString(cstate, "\r\n");
676#endif
677 break;
678 case COPY_FRONTEND:
679 /* The FE/BE protocol uses \n as newline for all platforms */
680 CopySendChar(cstate, '\n');
681 break;
682 default:
683 break;
684 }
685
686 /* Now take the actions related to the end of a row */
687 CopySendEndOfRow(cstate);
688}
689
690/*
691 * These functions do apply some data conversion
692 */
693
694/*
695 * CopySendInt32 sends an int32 in network byte order
696 */
697static inline void
699{
700 uint32 buf;
701
702 buf = pg_hton32((uint32) val);
703 CopySendData(cstate, &buf, sizeof(buf));
704}
705
706/*
707 * CopySendInt16 sends an int16 in network byte order
708 */
709static inline void
711{
712 uint16 buf;
713
714 buf = pg_hton16((uint16) val);
715 CopySendData(cstate, &buf, sizeof(buf));
716}
717
718/*
719 * Closes the pipe to an external program, checking the pclose() return code.
720 */
721static void
723{
724 int pclose_rc;
725
726 Assert(cstate->is_program);
727
729 if (pclose_rc == -1)
732 errmsg("could not close pipe to external command: %m")));
733 else if (pclose_rc != 0)
734 {
737 errmsg("program \"%s\" failed",
738 cstate->filename),
740 }
741}
742
743/*
744 * Release resources allocated in a cstate for COPY TO.
745 */
746static void
748{
749 if (cstate->is_program)
750 {
751 ClosePipeToProgram(cstate);
752 }
753 else
754 {
755 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
758 errmsg("could not close file \"%s\": %m",
759 cstate->filename)));
760 }
761
763
765
766 if (cstate->partitions)
767 list_free(cstate->partitions);
768
769 pfree(cstate);
770}
771
772/*
773 * Setup CopyToState to read tuples from a table or a query for COPY TO.
774 *
775 * 'rel': Relation to be copied
776 * 'raw_query': Query whose results are to be copied
777 * 'queryRelId': OID of base relation to convert to a query (for RLS)
778 * 'filename': Name of server-local file to write, NULL for STDOUT
779 * 'is_program': true if 'filename' is program to execute
780 * 'data_dest_cb': Callback that processes the output data
781 * 'attnamelist': List of char *, columns to include. NIL selects all cols.
782 * 'options': List of DefElem. See copy_opt_item in gram.y for selections.
783 *
784 * Returns a CopyToState, to be passed to DoCopyTo() and related functions.
785 */
788 Relation rel,
791 const char *filename,
792 bool is_program,
793 copy_data_dest_cb data_dest_cb,
795 List *options)
796{
797 CopyToState cstate;
798 bool pipe = (filename == NULL && data_dest_cb == NULL);
799 TupleDesc tupDesc;
800 int num_phys_attrs;
801 MemoryContext oldcontext;
802 const int progress_cols[] = {
805 };
806 int64 progress_vals[] = {
808 0
809 };
810 List *children = NIL;
811
812 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
813 {
814 if (rel->rd_rel->relkind == RELKIND_VIEW)
817 errmsg("cannot copy from view \"%s\"",
819 errhint("Try the COPY (SELECT ...) TO variant.")));
820 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
821 {
822 if (!RelationIsPopulated(rel))
825 errmsg("cannot copy from unpopulated materialized view \"%s\"",
827 errhint("Use the REFRESH MATERIALIZED VIEW command."));
828 }
829 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
832 errmsg("cannot copy from foreign table \"%s\"",
834 errhint("Try the COPY (SELECT ...) TO variant.")));
835 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
838 errmsg("cannot copy from sequence \"%s\"",
840 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
841 {
842 /*
843 * Collect OIDs of relation containing data, so that later
844 * DoCopyTo can copy the data from them.
845 */
847
848 foreach_oid(child, children)
849 {
850 char relkind = get_rel_relkind(child);
851
852 if (relkind == RELKIND_FOREIGN_TABLE)
853 {
854 char *relation_name = get_rel_name(child);
855
858 errmsg("cannot copy from foreign table \"%s\"", relation_name),
859 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
860 relation_name, RelationGetRelationName(rel)),
861 errhint("Try the COPY (SELECT ...) TO variant."));
862 }
863
864 /* Exclude tables with no data */
865 if (RELKIND_HAS_PARTITIONS(relkind))
866 children = foreach_delete_current(children, child);
867 }
868 }
869 else
872 errmsg("cannot copy from non-table relation \"%s\"",
874 }
875
876
877 /* Allocate workspace and zero all fields */
879
880 /*
881 * We allocate everything used by a cstate in a new memory context. This
882 * avoids memory leaks during repeated use of COPY in a query.
883 */
885 "COPY",
887
888 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
889
890 /* Extract options from the statement node tree */
891 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
892
893 /* Set format routine */
894 cstate->routine = CopyToGetRoutine(&cstate->opts);
895
896 /* Process the source/target relation or query */
897 if (rel)
898 {
900
901 cstate->rel = rel;
902
903 tupDesc = RelationGetDescr(cstate->rel);
904 cstate->partitions = children;
905 cstate->tupDesc = tupDesc;
906 }
907 else
908 {
910 Query *query;
912 DestReceiver *dest;
913
914 cstate->rel = NULL;
915 cstate->partitions = NIL;
916
917 /*
918 * Run parse analysis and rewrite. Note this also acquires sufficient
919 * locks on the source table(s).
920 */
922 pstate->p_sourcetext, NULL, 0,
923 NULL);
924
925 /* check that we got back something we can work with */
926 if (rewritten == NIL)
927 {
930 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
931 }
932 else if (list_length(rewritten) > 1)
933 {
934 ListCell *lc;
935
936 /* examine queries to determine which error message to issue */
937 foreach(lc, rewritten)
938 {
939 Query *q = lfirst_node(Query, lc);
940
941 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
944 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
945 if (q->querySource == QSRC_NON_INSTEAD_RULE)
948 errmsg("DO ALSO rules are not supported for COPY")));
949 }
950
953 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
954 }
955
956 query = linitial_node(Query, rewritten);
957
958 /* The grammar allows SELECT INTO, but we don't support that */
959 if (query->utilityStmt != NULL &&
963 errmsg("COPY (SELECT INTO) is not supported")));
964
965 /* The only other utility command we could see is NOTIFY */
966 if (query->utilityStmt != NULL)
969 errmsg("COPY query must not be a utility command")));
970
971 /*
972 * Similarly the grammar doesn't enforce the presence of a RETURNING
973 * clause, but this is required here.
974 */
975 if (query->commandType != CMD_SELECT &&
976 query->returningList == NIL)
977 {
978 Assert(query->commandType == CMD_INSERT ||
979 query->commandType == CMD_UPDATE ||
980 query->commandType == CMD_DELETE ||
981 query->commandType == CMD_MERGE);
982
985 errmsg("COPY query must have a RETURNING clause")));
986 }
987
988 /* plan the query */
989 plan = pg_plan_query(query, pstate->p_sourcetext,
991
992 /*
993 * With row-level security and a user using "COPY relation TO", we
994 * have to convert the "COPY relation TO" to a query-based COPY (eg:
995 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
996 * add in any RLS clauses.
997 *
998 * When this happens, we are passed in the relid of the originally
999 * found relation (which we have locked). As the planner will look up
1000 * the relation again, we double-check here to make sure it found the
1001 * same one that we have locked.
1002 */
1003 if (queryRelId != InvalidOid)
1004 {
1005 /*
1006 * Note that with RLS involved there may be multiple relations,
1007 * and while the one we need is almost certainly first, we don't
1008 * make any guarantees of that in the planner, so check the whole
1009 * list and make sure we find the original relation.
1010 */
1011 if (!list_member_oid(plan->relationOids, queryRelId))
1012 ereport(ERROR,
1014 errmsg("relation referenced by COPY statement has changed")));
1015 }
1016
1017 /*
1018 * Use a snapshot with an updated command ID to ensure this query sees
1019 * results of any previously executed queries.
1020 */
1023
1024 /* Create dest receiver for COPY OUT */
1026 ((DR_copy *) dest)->cstate = cstate;
1027
1028 /* Create a QueryDesc requesting no output */
1029 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
1032 dest, NULL, NULL, 0);
1033
1034 /*
1035 * Call ExecutorStart to prepare the plan for execution.
1036 *
1037 * ExecutorStart computes a result tupdesc for us
1038 */
1039 ExecutorStart(cstate->queryDesc, 0);
1040
1041 tupDesc = cstate->queryDesc->tupDesc;
1042 tupDesc = BlessTupleDesc(tupDesc);
1043 cstate->tupDesc = tupDesc;
1044 }
1045
1046 /* Generate or convert list of attributes to process */
1047 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1048
1049 /* Set up JSON-specific state */
1050 if (cstate->opts.format == COPY_FORMAT_JSON)
1051 {
1052 cstate->json_buf = makeStringInfo();
1053
1054 /*
1055 * Build a projected TupleDesc describing only the selected columns so
1056 * that composite_to_json() emits the right column names and types;
1057 * needed when an explicit column list was given (possibly with a
1058 * different column order) or when generated columns are excluded from
1059 * the output.
1060 */
1061 if (rel && (attnamelist != NIL ||
1062 list_length(cstate->attnumlist) < tupDesc->natts))
1063 {
1064 int natts = list_length(cstate->attnumlist);
1065 TupleDesc resultDesc;
1066
1067 resultDesc = CreateTemplateTupleDesc(natts);
1068
1069 foreach_int(attnum, cstate->attnumlist)
1070 {
1071 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1072
1073 TupleDescInitEntry(resultDesc,
1075 NameStr(attr->attname),
1076 attr->atttypid,
1077 attr->atttypmod,
1078 attr->attndims);
1079 }
1080
1081 TupleDescFinalize(resultDesc);
1082 cstate->tupDesc = BlessTupleDesc(resultDesc);
1083
1084 /*
1085 * Pre-allocate arrays for projecting selected column values into
1086 * sequential positions matching the custom TupleDesc.
1087 */
1088 cstate->json_projvalues = palloc_array(Datum, natts);
1089 cstate->json_projnulls = palloc_array(bool, natts);
1090 }
1091 }
1092
1093 num_phys_attrs = tupDesc->natts;
1094
1095 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
1096 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1097 if (cstate->opts.force_quote_all)
1098 {
1099 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
1100 }
1101 else if (cstate->opts.force_quote)
1102 {
1103 List *attnums;
1104 ListCell *cur;
1105
1106 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
1107
1108 foreach(cur, attnums)
1109 {
1110 int attnum = lfirst_int(cur);
1111 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1112
1113 if (!list_member_int(cstate->attnumlist, attnum))
1114 ereport(ERROR,
1116 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
1117 errmsg("%s column \"%s\" not referenced by COPY",
1118 "FORCE_QUOTE", NameStr(attr->attname))));
1119 cstate->opts.force_quote_flags[attnum - 1] = true;
1120 }
1121 }
1122
1123 /* Use client encoding when ENCODING option is not specified. */
1124 if (cstate->opts.file_encoding < 0)
1126 else
1127 cstate->file_encoding = cstate->opts.file_encoding;
1128
1129 /*
1130 * Set up encoding conversion info if the file and server encodings differ
1131 * (see also pg_server_to_any).
1132 */
1133 if (cstate->file_encoding == GetDatabaseEncoding() ||
1134 cstate->file_encoding == PG_SQL_ASCII)
1135 cstate->need_transcoding = false;
1136 else
1137 cstate->need_transcoding = true;
1138
1139 /* See Multibyte encoding comment above */
1141
1142 cstate->copy_dest = COPY_FILE; /* default */
1143
1144 if (data_dest_cb)
1145 {
1147 cstate->copy_dest = COPY_CALLBACK;
1148 cstate->data_dest_cb = data_dest_cb;
1149 }
1150 else if (pipe)
1151 {
1153
1154 Assert(!is_program); /* the grammar does not allow this */
1156 cstate->copy_file = stdout;
1157 }
1158 else
1159 {
1160 cstate->filename = pstrdup(filename);
1161 cstate->is_program = is_program;
1162
1163 if (is_program)
1164 {
1166 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
1167 if (cstate->copy_file == NULL)
1168 ereport(ERROR,
1170 errmsg("could not execute command \"%s\": %m",
1171 cstate->filename)));
1172 }
1173 else
1174 {
1175 mode_t oumask; /* Pre-existing umask value */
1176 struct stat st;
1177
1179
1180 /*
1181 * Prevent write to relative path ... too easy to shoot oneself in
1182 * the foot by overwriting a database file ...
1183 */
1185 ereport(ERROR,
1187 errmsg("relative path not allowed for COPY to file")));
1188
1190 PG_TRY();
1191 {
1192 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
1193 }
1194 PG_FINALLY();
1195 {
1196 umask(oumask);
1197 }
1198 PG_END_TRY();
1199 if (cstate->copy_file == NULL)
1200 {
1201 /* copy errno because ereport subfunctions might change it */
1202 int save_errno = errno;
1203
1204 ereport(ERROR,
1206 errmsg("could not open file \"%s\" for writing: %m",
1207 cstate->filename),
1208 (save_errno == ENOENT || save_errno == EACCES) ?
1209 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1210 "You may want a client-side facility such as psql's \\copy.") : 0));
1211 }
1212
1213 if (fstat(fileno(cstate->copy_file), &st))
1214 ereport(ERROR,
1216 errmsg("could not stat file \"%s\": %m",
1217 cstate->filename)));
1218
1219 if (S_ISDIR(st.st_mode))
1220 ereport(ERROR,
1222 errmsg("\"%s\" is a directory", cstate->filename)));
1223 }
1224 }
1225
1226 /* initialize progress */
1228 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1230
1231 cstate->bytes_processed = 0;
1232
1233 MemoryContextSwitchTo(oldcontext);
1234
1235 return cstate;
1236}
1237
1238/*
1239 * Clean up storage and release resources for COPY TO.
1240 */
1241void
1243{
1244 if (cstate->queryDesc != NULL)
1245 {
1246 /* Close down the query and free resources. */
1247 ExecutorFinish(cstate->queryDesc);
1248 ExecutorEnd(cstate->queryDesc);
1249 FreeQueryDesc(cstate->queryDesc);
1251 }
1252
1253 /* Clean up storage */
1254 EndCopy(cstate);
1255}
1256
1257/*
1258 * Copy from relation or query TO file.
1259 *
1260 * Returns the number of rows processed.
1261 */
1262uint64
1264{
1265 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1266 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1267 TupleDesc tupDesc;
1268 int num_phys_attrs;
1269 ListCell *cur;
1270 uint64 processed = 0;
1271
1272 if (fe_copy)
1273 SendCopyBegin(cstate);
1274
1275 if (cstate->rel)
1276 tupDesc = RelationGetDescr(cstate->rel);
1277 else
1278 tupDesc = cstate->queryDesc->tupDesc;
1279 num_phys_attrs = tupDesc->natts;
1280 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1281
1282 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1283 cstate->fe_msgbuf = makeStringInfo();
1284
1285 /* Get info about the columns we need to process. */
1286 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1287 foreach(cur, cstate->attnumlist)
1288 {
1289 int attnum = lfirst_int(cur);
1290 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1291
1292 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1293 &cstate->out_functions[attnum - 1]);
1294 }
1295
1296 /*
1297 * Create a temporary memory context that we can reset once per row to
1298 * recover palloc'd memory. This avoids any problems with leaks inside
1299 * datatype output routines, and should be faster than retail pfree's
1300 * anyway. (We don't need a whole econtext as CopyFrom does.)
1301 */
1303 "COPY TO",
1305
1306 cstate->routine->CopyToStart(cstate, tupDesc);
1307
1308 if (cstate->rel)
1309 {
1310 /*
1311 * If COPY TO source table is a partitioned table, then open each
1312 * partition and process each individual partition.
1313 */
1314 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1315 {
1316 foreach_oid(child, cstate->partitions)
1317 {
1319
1320 /* We already got the lock in BeginCopyTo */
1321 scan_rel = table_open(child, NoLock);
1322 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1324 }
1325 }
1326 else
1327 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1328 }
1329 else
1330 {
1331 /* run the plan --- the dest receiver will send tuples */
1333 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1334 }
1335
1336 cstate->routine->CopyToEnd(cstate);
1337
1339
1340 if (fe_copy)
1341 SendCopyEnd(cstate);
1342
1343 return processed;
1344}
1345
1346/*
1347 * Scans a single table and exports its rows to the COPY destination.
1348 *
1349 * root_rel can be set to the root table of rel if rel is a partition
1350 * table so that we can send tuples in root_rel's rowtype, which might
1351 * differ from individual partitions.
1352 */
1353static void
1355{
1356 TupleTableSlot *slot;
1357 TableScanDesc scandesc;
1358 AttrMap *map = NULL;
1360
1361 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL,
1362 SO_NONE);
1363 slot = table_slot_create(rel, NULL);
1364
1365 /*
1366 * If we are exporting partition data here, we check if converting tuples
1367 * to the root table's rowtype, because a partition might have column
1368 * order different than its root table.
1369 */
1370 if (root_rel != NULL)
1371 {
1375 false);
1376 }
1377
1378 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1379 {
1380 TupleTableSlot *copyslot;
1381
1383
1384 if (map != NULL)
1385 copyslot = execute_attr_map_slot(map, slot, root_slot);
1386 else
1387 {
1388 /* Deconstruct the tuple */
1389 slot_getallattrs(slot);
1390 copyslot = slot;
1391 }
1392
1393 /* Format and send the data */
1394 CopyOneRowTo(cstate, copyslot);
1395
1396 /*
1397 * Increment the number of processed tuples, and report the progress.
1398 */
1400 ++(*processed));
1401 }
1402
1404
1405 if (root_slot != NULL)
1407
1408 if (map != NULL)
1409 free_attrmap(map);
1410
1411 table_endscan(scandesc);
1412}
1413
1414/*
1415 * Emit one row during DoCopyTo().
1416 */
1417static inline void
1419{
1420 MemoryContext oldcontext;
1421
1423 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1424
1425 /* Make sure the tuple is fully deconstructed */
1426 slot_getallattrs(slot);
1427
1428 cstate->routine->CopyToOneRow(cstate, slot);
1429
1430 MemoryContextSwitchTo(oldcontext);
1431}
1432
1433/*
1434 * Send text representation of one attribute, with conversion and escaping
1435 */
1436#define DUMPSOFAR() \
1437 do { \
1438 if (ptr > start) \
1439 CopySendData(cstate, start, ptr - start); \
1440 } while (0)
1441
1442static void
1443CopyAttributeOutText(CopyToState cstate, const char *string)
1444{
1445 const char *ptr;
1446 const char *start;
1447 char c;
1448 char delimc = cstate->opts.delim[0];
1449
1450 if (cstate->need_transcoding)
1451 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1452 else
1453 ptr = string;
1454
1455 /*
1456 * We have to grovel through the string searching for control characters
1457 * and instances of the delimiter character. In most cases, though, these
1458 * are infrequent. To avoid overhead from calling CopySendData once per
1459 * character, we dump out all characters between escaped characters in a
1460 * single call. The loop invariant is that the data from "start" to "ptr"
1461 * can be sent literally, but hasn't yet been.
1462 *
1463 * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1464 * in valid backend encodings, extra bytes of a multibyte character never
1465 * look like ASCII. This loop is sufficiently performance-critical that
1466 * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1467 * of the normal safe-encoding path.
1468 */
1469 if (cstate->encoding_embeds_ascii)
1470 {
1471 start = ptr;
1472 while ((c = *ptr) != '\0')
1473 {
1474 if ((unsigned char) c < (unsigned char) 0x20)
1475 {
1476 /*
1477 * \r and \n must be escaped, the others are traditional. We
1478 * prefer to dump these using the C-like notation, rather than
1479 * a backslash and the literal character, because it makes the
1480 * dump file a bit more proof against Microsoftish data
1481 * mangling.
1482 */
1483 switch (c)
1484 {
1485 case '\b':
1486 c = 'b';
1487 break;
1488 case '\f':
1489 c = 'f';
1490 break;
1491 case '\n':
1492 c = 'n';
1493 break;
1494 case '\r':
1495 c = 'r';
1496 break;
1497 case '\t':
1498 c = 't';
1499 break;
1500 case '\v':
1501 c = 'v';
1502 break;
1503 default:
1504 /* If it's the delimiter, must backslash it */
1505 if (c == delimc)
1506 break;
1507 /* All ASCII control chars are length 1 */
1508 ptr++;
1509 continue; /* fall to end of loop */
1510 }
1511 /* if we get here, we need to convert the control char */
1512 DUMPSOFAR();
1513 CopySendChar(cstate, '\\');
1514 CopySendChar(cstate, c);
1515 start = ++ptr; /* do not include char in next run */
1516 }
1517 else if (c == '\\' || c == delimc)
1518 {
1519 DUMPSOFAR();
1520 CopySendChar(cstate, '\\');
1521 start = ptr++; /* we include char in next run */
1522 }
1523 else if (IS_HIGHBIT_SET(c))
1524 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1525 else
1526 ptr++;
1527 }
1528 }
1529 else
1530 {
1531 start = ptr;
1532 while ((c = *ptr) != '\0')
1533 {
1534 if ((unsigned char) c < (unsigned char) 0x20)
1535 {
1536 /*
1537 * \r and \n must be escaped, the others are traditional. We
1538 * prefer to dump these using the C-like notation, rather than
1539 * a backslash and the literal character, because it makes the
1540 * dump file a bit more proof against Microsoftish data
1541 * mangling.
1542 */
1543 switch (c)
1544 {
1545 case '\b':
1546 c = 'b';
1547 break;
1548 case '\f':
1549 c = 'f';
1550 break;
1551 case '\n':
1552 c = 'n';
1553 break;
1554 case '\r':
1555 c = 'r';
1556 break;
1557 case '\t':
1558 c = 't';
1559 break;
1560 case '\v':
1561 c = 'v';
1562 break;
1563 default:
1564 /* If it's the delimiter, must backslash it */
1565 if (c == delimc)
1566 break;
1567 /* All ASCII control chars are length 1 */
1568 ptr++;
1569 continue; /* fall to end of loop */
1570 }
1571 /* if we get here, we need to convert the control char */
1572 DUMPSOFAR();
1573 CopySendChar(cstate, '\\');
1574 CopySendChar(cstate, c);
1575 start = ++ptr; /* do not include char in next run */
1576 }
1577 else if (c == '\\' || c == delimc)
1578 {
1579 DUMPSOFAR();
1580 CopySendChar(cstate, '\\');
1581 start = ptr++; /* we include char in next run */
1582 }
1583 else
1584 ptr++;
1585 }
1586 }
1587
1588 DUMPSOFAR();
1589}
1590
1591/*
1592 * Send text representation of one attribute, with conversion and
1593 * CSV-style escaping
1594 */
1595static void
1596CopyAttributeOutCSV(CopyToState cstate, const char *string,
1597 bool use_quote)
1598{
1599 const char *ptr;
1600 const char *start;
1601 char c;
1602 char delimc = cstate->opts.delim[0];
1603 char quotec = cstate->opts.quote[0];
1604 char escapec = cstate->opts.escape[0];
1605 bool single_attr = (list_length(cstate->attnumlist) == 1);
1606
1607 /* force quoting if it matches null_print (before conversion!) */
1608 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1609 use_quote = true;
1610
1611 if (cstate->need_transcoding)
1612 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1613 else
1614 ptr = string;
1615
1616 /*
1617 * Make a preliminary pass to discover if it needs quoting
1618 */
1619 if (!use_quote)
1620 {
1621 /*
1622 * Quote '\.' if it appears alone on a line, so that it will not be
1623 * interpreted as an end-of-data marker. (PG 18 and up will not
1624 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1625 * we want the data to be loadable by older versions too. Also, this
1626 * avoids breaking clients that are still using PQgetline().)
1627 */
1628 if (single_attr && strcmp(ptr, "\\.") == 0)
1629 use_quote = true;
1630 else
1631 {
1632 const char *tptr = ptr;
1633
1634 while ((c = *tptr) != '\0')
1635 {
1636 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1637 {
1638 use_quote = true;
1639 break;
1640 }
1641 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1643 else
1644 tptr++;
1645 }
1646 }
1647 }
1648
1649 if (use_quote)
1650 {
1651 CopySendChar(cstate, quotec);
1652
1653 /*
1654 * We adopt the same optimization strategy as in CopyAttributeOutText
1655 */
1656 start = ptr;
1657 while ((c = *ptr) != '\0')
1658 {
1659 if (c == quotec || c == escapec)
1660 {
1661 DUMPSOFAR();
1662 CopySendChar(cstate, escapec);
1663 start = ptr; /* we include char in next run */
1664 }
1665 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1666 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1667 else
1668 ptr++;
1669 }
1670 DUMPSOFAR();
1671
1672 CopySendChar(cstate, quotec);
1673 }
1674 else
1675 {
1676 /* If it doesn't need quoting, we can just dump it as-is */
1677 CopySendString(cstate, ptr);
1678 }
1679}
1680
1681/*
1682 * copy_dest_startup --- executor startup
1683 */
1684static void
1686{
1687 /* no-op */
1688}
1689
1690/*
1691 * copy_dest_receive --- receive one tuple
1692 */
1693static bool
1695{
1696 DR_copy *myState = (DR_copy *) self;
1697 CopyToState cstate = myState->cstate;
1698
1699 /* Send the data */
1700 CopyOneRowTo(cstate, slot);
1701
1702 /* Increment the number of processed tuples, and report the progress */
1704 ++myState->processed);
1705
1706 return true;
1707}
1708
1709/*
1710 * copy_dest_shutdown --- executor end
1711 */
1712static void
1714{
1715 /* no-op */
1716}
1717
1718/*
1719 * copy_dest_destroy --- release DestReceiver object
1720 */
1721static void
1723{
1724 pfree(self);
1725}
1726
1727/*
1728 * CreateCopyDestReceiver -- create a suitable DestReceiver object
1729 */
1732{
1733 DR_copy *self = palloc_object(DR_copy);
1734
1739 self->pub.mydest = DestCopyOut;
1740
1741 self->cstate = NULL; /* will be set later */
1742 self->processed = 0;
1743
1744 return (DestReceiver *) self;
1745}
void free_attrmap(AttrMap *map)
Definition attmap.c:56
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
Definition attmap.c:261
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition copy.c:1068
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition copy.c:581
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_COPY
#define NameStr(name)
Definition c.h:894
#define IS_HIGHBIT_SET(ch)
Definition c.h:1303
#define VARHDRSZ
Definition c.h:840
#define Assert(condition)
Definition c.h:1002
int64_t int64
Definition c.h:680
#define pg_attribute_always_inline
Definition c.h:364
int16_t int16
Definition c.h:678
int32_t int32
Definition c.h:679
uint64_t uint64
Definition c.h:684
uint16_t uint16
Definition c.h:682
uint32_t uint32
Definition c.h:683
#define PG_BINARY_W
Definition c.h:1448
#define MemSet(start, val, len)
Definition c.h:1166
static void CopyToBinaryOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition copyto.c:477
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:489
static void CopySendInt32(CopyToState cstate, int32 val)
Definition copyto.c:698
static void ClosePipeToProgram(CopyToState cstate)
Definition copyto.c:722
static const CopyToRoutine CopyToRoutineCSV
Definition copyto.c:176
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition copyto.c:1694
static void CopyAttributeOutCSV(CopyToState cstate, const char *string, bool use_quote)
Definition copyto.c:1596
uint64 DoCopyTo(CopyToState cstate)
Definition copyto.c:1263
static void CopyToTextLikeEnd(CopyToState cstate)
Definition copyto.c:341
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition copyto.c:1443
#define DUMPSOFAR()
Definition copyto.c:1436
static const CopyToRoutine CopyToRoutineText
Definition copyto.c:168
static void CopySendInt16(CopyToState cstate, int16 val)
Definition copyto.c:710
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition copyto.c:585
static void CopyToTextOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:282
static void CopySendChar(CopyToState cstate, char c)
Definition copyto.c:597
DestReceiver * CreateCopyDestReceiver(void)
Definition copyto.c:1731
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition copyto.c:201
static void CopySendTextLikeEndOfRow(CopyToState cstate)
Definition copyto.c:666
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition copyto.c:1354
static void EndCopy(CopyToState cstate)
Definition copyto.c:747
static void copy_dest_destroy(DestReceiver *self)
Definition copyto.c:1722
CopyDest
Definition copyto.c:50
@ COPY_FILE
Definition copyto.c:51
@ COPY_CALLBACK
Definition copyto.c:53
@ COPY_FRONTEND
Definition copyto.c:52
static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition copyto.c:270
CopyToState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, copy_data_dest_cb data_dest_cb, List *attnamelist, List *options)
Definition copyto.c:787
static void copy_dest_shutdown(DestReceiver *self)
Definition copyto.c:1713
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition copyto.c:1685
static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:216
static void SendCopyBegin(CopyToState cstate)
Definition copyto.c:535
static void SendCopyEnd(CopyToState cstate)
Definition copyto.c:566
static void CopySendEndOfRow(CopyToState cstate)
Definition copyto.c:603
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:1418
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition copyto.c:301
static void CopyToJsonOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:359
static void CopySendString(CopyToState cstate, const char *str)
Definition copyto.c:591
static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition copyto.c:289
static void CopyToJsonEnd(CopyToState cstate)
Definition copyto.c:348
static const char BinarySignature[11]
Definition copyto.c:124
void EndCopyTo(CopyToState cstate)
Definition copyto.c:1242
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition copyto.c:458
static const CopyToRoutine CopyToRoutineJson
Definition copyto.c:184
static const CopyToRoutine CopyToRoutineBinary
Definition copyto.c:192
static void CopyToBinaryEnd(CopyToState cstate)
Definition copyto.c:522
static DataChecksumsWorkerOperation operation
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition dest.c:113
@ DestRemote
Definition dest.h:89
@ DestCopyOut
Definition dest.h:95
struct cursor * cur
Definition ecpg.c:29
int errcode_for_file_access(void)
Definition elog.c:898
int errcode(int sqlerrcode)
Definition elog.c:875
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define PG_TRY(...)
Definition elog.h:374
#define PG_END_TRY(...)
Definition elog.h:399
#define ERROR
Definition elog.h:40
#define PG_FINALLY(...)
Definition elog.h:391
#define ereport(elevel,...)
Definition elog.h:152
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:477
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:417
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:124
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:308
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot)
FILE * OpenPipeStream(const char *command, const char *mode)
Definition fd.c:2731
int ClosePipeStream(FILE *file)
Definition fd.c:3039
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
#define palloc_object(type)
Definition fe_memutils.h:89
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define palloc0_object(type)
Definition fe_memutils.h:90
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1745
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition fmgr.c:1684
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
return str start
const char * str
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
@ COPY_FORMAT_CSV
Definition copy.h:59
@ COPY_FORMAT_JSON
Definition copy.h:60
@ COPY_FORMAT_BINARY
Definition copy.h:58
void(* copy_data_dest_cb)(void *data, int len)
Definition copy.h:107
#define COPY_HEADER_TRUE
Definition copy.h:28
long val
Definition informix.c:689
static struct @175 value
int i
Definition isn.c:77
void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition json.c:521
#define pq_putmessage(msgtype, s, len)
Definition libpq.h:52
void list_free(List *list)
Definition list.c:1546
bool list_member_int(const List *list, int datum)
Definition list.c:702
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
#define NoLock
Definition lockdefs.h:34
#define AccessShareLock
Definition lockdefs.h:36
char * get_rel_name(Oid relid)
Definition lsyscache.c:2242
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition lsyscache.c:3289
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3223
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2317
int GetDatabaseEncoding(void)
Definition mbutils.c:1389
int pg_get_client_encoding(void)
Definition mbutils.c:345
char * pg_server_to_any(const char *s, int len, int encoding)
Definition mbutils.c:760
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:406
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pfree(void *pointer)
Definition mcxt.c:1619
void * palloc0(Size size)
Definition mcxt.c:1420
void * palloc(Size size)
Definition mcxt.c:1390
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
#define IsA(nodeptr, _type_)
Definition nodes.h:162
@ CMD_MERGE
Definition nodes.h:277
@ CMD_INSERT
Definition nodes.h:275
@ CMD_DELETE
Definition nodes.h:276
@ CMD_UPDATE
Definition nodes.h:274
@ CMD_SELECT
Definition nodes.h:273
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
@ QSRC_NON_INSTEAD_RULE
Definition parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
static AmcheckOptions opts
Definition pg_amcheck.c:112
NameData attname
int16 attnum
FormData_pg_attribute * Form_pg_attribute
static char format
#define pg_hton32(x)
Definition pg_bswap.h:121
#define pg_hton16(x)
Definition pg_bswap.h:120
static char * filename
Definition pg_dumpall.c:120
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial_node(type, l)
Definition pg_list.h:181
#define NIL
Definition pg_list.h:68
#define foreach_current_index(var_or_cell)
Definition pg_list.h:435
#define lfirst_int(lc)
Definition pg_list.h:173
#define foreach_delete_current(lst, var_or_cell)
Definition pg_list.h:423
#define foreach_oid(var, lst)
Definition pg_list.h:503
#define foreach_int(var, lst)
Definition pg_list.h:502
#define plan(x)
Definition pg_regress.c:164
static char buf[DEFAULT_XLOG_SEG_SIZE]
@ PG_SQL_ASCII
Definition pg_wchar.h:76
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition pg_wchar.h:137
#define is_absolute_path(filename)
Definition port.h:105
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition postgres.c:900
CommandDest whereToSendOutput
Definition postgres.c:97
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition postgres.c:683
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
unsigned int Oid
void pq_putemptymessage(char msgtype)
Definition pqformat.c:387
void pq_endmessage(StringInfo buf)
Definition pqformat.c:296
void pq_beginmessage(StringInfo buf, char msgtype)
Definition pqformat.c:88
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition pqformat.h:160
static void pq_sendint16(StringInfo buf, uint16 i)
Definition pqformat.h:136
void FreeQueryDesc(QueryDesc *qdesc)
Definition pquery.c:107
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition pquery.c:68
char * c
static int fb(int x)
char string[11]
#define PROGRESS_COPY_COMMAND
Definition progress.h:177
#define PROGRESS_COPY_TYPE_FILE
Definition progress.h:186
#define PROGRESS_COPY_BYTES_PROCESSED
Definition progress.h:173
#define PROGRESS_COPY_COMMAND_TO
Definition progress.h:183
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition progress.h:175
#define PROGRESS_COPY_TYPE
Definition progress.h:178
#define PROGRESS_COPY_TYPE_PROGRAM
Definition progress.h:187
#define PROGRESS_COPY_TYPE_CALLBACK
Definition progress.h:189
#define PROGRESS_COPY_TYPE_PIPE
Definition progress.h:188
#define PqMsg_CopyDone
Definition protocol.h:64
#define PqMsg_CopyData
Definition protocol.h:65
#define PqMsg_CopyOutResponse
Definition protocol.h:46
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetRelationName(relation)
Definition rel.h:550
#define RelationIsPopulated(relation)
Definition rel.h:697
@ ForwardScanDirection
Definition sdir.h:28
void UpdateActiveSnapshotCommandId(void)
Definition snapmgr.c:744
void PopActiveSnapshot(void)
Definition snapmgr.c:775
void PushCopiedSnapshot(Snapshot snapshot)
Definition snapmgr.c:732
Snapshot GetActiveSnapshot(void)
Definition snapmgr.c:800
#define InvalidSnapshot
Definition snapshot.h:119
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
void resetStringInfo(StringInfo str)
Definition stringinfo.c:126
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231
int header_line
Definition copy.h:75
CopyFormat format
Definition copy.h:73
bool force_quote_all
Definition copy.h:86
int null_print_len
Definition copy.h:78
char * quote
Definition copy.h:83
bool force_array
Definition copy.h:91
List * force_quote
Definition copy.h:85
char * escape
Definition copy.h:84
char * null_print
Definition copy.h:77
char * delim
Definition copy.h:82
bool * force_quote_flags
Definition copy.h:87
char * null_print_client
Definition copy.h:79
int file_encoding
Definition copy.h:71
void(* CopyToOutFunc)(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition copyapi.h:34
void(* CopyToOneRow)(CopyToState cstate, TupleTableSlot *slot)
Definition copyapi.h:49
void(* CopyToEnd)(CopyToState cstate)
Definition copyapi.h:54
void(* CopyToStart)(CopyToState cstate, TupleDesc tupDesc)
Definition copyapi.h:44
FmgrInfo * out_functions
Definition copyto.c:110
MemoryContext copycontext
Definition copyto.c:108
Node * whereClause
Definition copyto.c:102
Relation rel
Definition copyto.c:86
Datum * json_projvalues
Definition copyto.c:96
const CopyToRoutine * routine
Definition copyto.c:74
copy_data_dest_cb data_dest_cb
Definition copyto.c:99
bool encoding_embeds_ascii
Definition copyto.c:83
CopyDest copy_dest
Definition copyto.c:77
bool need_transcoding
Definition copyto.c:82
bool is_program
Definition copyto.c:90
FILE * copy_file
Definition copyto.c:78
bool * json_projnulls
Definition copyto.c:98
int file_encoding
Definition copyto.c:81
MemoryContext rowcontext
Definition copyto.c:111
CopyFormatOptions opts
Definition copyto.c:101
uint64 bytes_processed
Definition copyto.c:112
bool json_row_delim_needed
Definition copyto.c:91
StringInfo fe_msgbuf
Definition copyto.c:79
char * filename
Definition copyto.c:89
List * attnumlist
Definition copyto.c:88
QueryDesc * queryDesc
Definition copyto.c:87
TupleDesc tupDesc
Definition copyto.c:94
List * partitions
Definition copyto.c:103
StringInfo json_buf
Definition copyto.c:92
CopyToState cstate
Definition copyto.c:119
DestReceiver pub
Definition copyto.c:118
uint64 processed
Definition copyto.c:120
Definition pg_list.h:54
Definition nodes.h:133
const char * p_sourcetext
Definition parse_node.h:214
DestReceiver * dest
Definition execdesc.h:41
TupleDesc tupDesc
Definition execdesc.h:49
List * returningList
Definition parsenodes.h:219
CmdType commandType
Definition parsenodes.h:124
Node * utilityStmt
Definition parsenodes.h:144
Form_pg_class rd_rel
Definition rel.h:111
TupleDesc tts_tupleDescriptor
Definition tuptable.h:129
bool * tts_isnull
Definition tuptable.h:133
Datum * tts_values
Definition tuptable.h:131
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition dest.h:126
CommandDest mydest
Definition dest.h:128
unsigned short st_mode
Definition win32_port.h:258
Definition c.h:835
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
@ SO_NONE
Definition tableam.h:49
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1061
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
Definition tableam.h:943
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1096
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition tupconvert.c:193
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:909
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
static void slot_getallattrs(TupleTableSlot *slot)
Definition tuptable.h:390
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA(const void *PTR)
Definition varatt.h:305
char * wait_result_to_str(int exitstatus)
Definition wait_error.c:33
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:67
static void pgstat_report_wait_end(void)
Definition wait_event.h:83
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition wchar.c:1935
#define S_IWOTH
Definition win32_port.h:306
#define S_ISDIR(m)
Definition win32_port.h:315
#define fstat
Definition win32_port.h:73
#define S_IWGRP
Definition win32_port.h:294