PostgreSQL Source Code git master
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-2025, 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 "catalog/pg_inherits.h"
24#include "commands/copyapi.h"
25#include "commands/progress.h"
26#include "executor/execdesc.h"
27#include "executor/executor.h"
28#include "executor/tuptable.h"
29#include "libpq/libpq.h"
30#include "libpq/pqformat.h"
31#include "mb/pg_wchar.h"
32#include "miscadmin.h"
33#include "pgstat.h"
34#include "storage/fd.h"
35#include "tcop/tcopprot.h"
36#include "utils/lsyscache.h"
37#include "utils/memutils.h"
38#include "utils/rel.h"
39#include "utils/snapmgr.h"
40
41/*
42 * Represents the different dest cases we need to worry about at
43 * the bottom level
44 */
45typedef enum CopyDest
46{
47 COPY_FILE, /* to file (or a piped program) */
48 COPY_FRONTEND, /* to frontend */
49 COPY_CALLBACK, /* to callback function */
51
52/*
53 * This struct contains all the state variables used throughout a COPY TO
54 * operation.
55 *
56 * Multi-byte encodings: all supported client-side encodings encode multi-byte
57 * characters by having the first byte's high bit set. Subsequent bytes of the
58 * character can have the high bit not set. When scanning data in such an
59 * encoding to look for a match to a single-byte (ie ASCII) character, we must
60 * use the full pg_encoding_mblen() machinery to skip over multibyte
61 * characters, else we might find a false match to a trailing byte. In
62 * supported server encodings, there is no possibility of a false match, and
63 * it's faster to make useless comparisons to trailing bytes than it is to
64 * invoke pg_encoding_mblen() to skip over them. encoding_embeds_ascii is true
65 * when we have to do it the hard way.
66 */
67typedef struct CopyToStateData
68{
69 /* format-specific routines */
71
72 /* low-level state data */
73 CopyDest copy_dest; /* type of copy source/destination */
74 FILE *copy_file; /* used if copy_dest == COPY_FILE */
75 StringInfo fe_msgbuf; /* used for all dests during COPY TO */
76
77 int file_encoding; /* file or remote side's character encoding */
78 bool need_transcoding; /* file encoding diff from server? */
79 bool encoding_embeds_ascii; /* ASCII can be non-first byte? */
80
81 /* parameters from the COPY command */
82 Relation rel; /* relation to copy to */
83 QueryDesc *queryDesc; /* executable query to copy from */
84 List *attnumlist; /* integer list of attnums to copy */
85 char *filename; /* filename, or NULL for STDOUT */
86 bool is_program; /* is 'filename' a program to popen? */
87 copy_data_dest_cb data_dest_cb; /* function for writing data */
88
90 Node *whereClause; /* WHERE condition (or NULL) */
91 List *partitions; /* OID list of partitions to copy data from */
92
93 /*
94 * Working state
95 */
96 MemoryContext copycontext; /* per-copy execution context */
97
98 FmgrInfo *out_functions; /* lookup info for output functions */
99 MemoryContext rowcontext; /* per-row evaluation context */
100 uint64 bytes_processed; /* number of bytes processed so far */
102
103/* DestReceiver for COPY (query) TO */
104typedef struct
105{
106 DestReceiver pub; /* publicly-known function pointers */
107 CopyToState cstate; /* CopyToStateData for the command */
108 uint64 processed; /* # of tuples processed */
109} DR_copy;
110
111/* NOTE: there's a copy of this in copyfromparse.c */
112static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
113
114
115/* non-export function prototypes */
116static void EndCopy(CopyToState cstate);
117static void ClosePipeToProgram(CopyToState cstate);
118static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot);
119static void CopyAttributeOutText(CopyToState cstate, const char *string);
120static void CopyAttributeOutCSV(CopyToState cstate, const char *string,
121 bool use_quote);
122static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel,
123 uint64 *processed);
124
125/* built-in format-specific routines */
126static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc);
127static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo);
128static void CopyToTextOneRow(CopyToState cstate, TupleTableSlot *slot);
129static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot);
130static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot,
131 bool is_csv);
132static void CopyToTextLikeEnd(CopyToState cstate);
133static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc);
134static void CopyToBinaryOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo);
135static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot);
136static void CopyToBinaryEnd(CopyToState cstate);
137
138/* Low-level communications functions */
139static void SendCopyBegin(CopyToState cstate);
140static void SendCopyEnd(CopyToState cstate);
141static void CopySendData(CopyToState cstate, const void *databuf, int datasize);
142static void CopySendString(CopyToState cstate, const char *str);
143static void CopySendChar(CopyToState cstate, char c);
144static void CopySendEndOfRow(CopyToState cstate);
145static void CopySendTextLikeEndOfRow(CopyToState cstate);
146static void CopySendInt32(CopyToState cstate, int32 val);
147static void CopySendInt16(CopyToState cstate, int16 val);
148
149/*
150 * COPY TO routines for built-in formats.
151 *
152 * CSV and text formats share the same TextLike routines except for the
153 * one-row callback.
154 */
155
156/* text format */
159 .CopyToOutFunc = CopyToTextLikeOutFunc,
160 .CopyToOneRow = CopyToTextOneRow,
161 .CopyToEnd = CopyToTextLikeEnd,
162};
163
164/* CSV format */
167 .CopyToOutFunc = CopyToTextLikeOutFunc,
168 .CopyToOneRow = CopyToCSVOneRow,
169 .CopyToEnd = CopyToTextLikeEnd,
170};
171
172/* binary format */
175 .CopyToOutFunc = CopyToBinaryOutFunc,
176 .CopyToOneRow = CopyToBinaryOneRow,
177 .CopyToEnd = CopyToBinaryEnd,
178};
179
180/* Return a COPY TO routine for the given options */
181static const CopyToRoutine *
183{
184 if (opts->csv_mode)
185 return &CopyToRoutineCSV;
186 else if (opts->binary)
187 return &CopyToRoutineBinary;
188
189 /* default is text */
190 return &CopyToRoutineText;
191}
192
193/* Implementation of the start callback for text and CSV formats */
194static void
196{
197 /*
198 * For non-binary copy, we need to convert null_print to file encoding,
199 * because it will be sent directly with CopySendString.
200 */
201 if (cstate->need_transcoding)
203 cstate->opts.null_print_len,
204 cstate->file_encoding);
205
206 /* if a header has been requested send the line */
207 if (cstate->opts.header_line == COPY_HEADER_TRUE)
208 {
209 ListCell *cur;
210 bool hdr_delim = false;
211
212 foreach(cur, cstate->attnumlist)
213 {
214 int attnum = lfirst_int(cur);
215 char *colname;
216
217 if (hdr_delim)
218 CopySendChar(cstate, cstate->opts.delim[0]);
219 hdr_delim = true;
220
221 colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
222
223 if (cstate->opts.csv_mode)
224 CopyAttributeOutCSV(cstate, colname, false);
225 else
226 CopyAttributeOutText(cstate, colname);
227 }
228
230 }
231}
232
233/*
234 * Implementation of the outfunc callback for text and CSV formats. Assign
235 * the output function data to the given *finfo.
236 */
237static void
239{
240 Oid func_oid;
241 bool is_varlena;
242
243 /* Set output function for an attribute */
244 getTypeOutputInfo(atttypid, &func_oid, &is_varlena);
245 fmgr_info(func_oid, finfo);
246}
247
248/* Implementation of the per-row callback for text format */
249static void
251{
252 CopyToTextLikeOneRow(cstate, slot, false);
253}
254
255/* Implementation of the per-row callback for CSV format */
256static void
258{
259 CopyToTextLikeOneRow(cstate, slot, true);
260}
261
262/*
263 * Workhorse for CopyToTextOneRow() and CopyToCSVOneRow().
264 *
265 * We use pg_attribute_always_inline to reduce function call overhead
266 * and to help compilers to optimize away the 'is_csv' condition.
267 */
270 TupleTableSlot *slot,
271 bool is_csv)
272{
273 bool need_delim = false;
274 FmgrInfo *out_functions = cstate->out_functions;
275
277 {
278 Datum value = slot->tts_values[attnum - 1];
279 bool isnull = slot->tts_isnull[attnum - 1];
280
281 if (need_delim)
282 CopySendChar(cstate, cstate->opts.delim[0]);
283 need_delim = true;
284
285 if (isnull)
286 {
287 CopySendString(cstate, cstate->opts.null_print_client);
288 }
289 else
290 {
291 char *string;
292
293 string = OutputFunctionCall(&out_functions[attnum - 1],
294 value);
295
296 if (is_csv)
297 CopyAttributeOutCSV(cstate, string,
298 cstate->opts.force_quote_flags[attnum - 1]);
299 else
300 CopyAttributeOutText(cstate, string);
301 }
302 }
303
305}
306
307/* Implementation of the end callback for text and CSV formats */
308static void
310{
311 /* Nothing to do here */
312}
313
314/*
315 * Implementation of the start callback for binary format. Send a header
316 * for a binary copy.
317 */
318static void
320{
321 int32 tmp;
322
323 /* Signature */
324 CopySendData(cstate, BinarySignature, 11);
325 /* Flags field */
326 tmp = 0;
327 CopySendInt32(cstate, tmp);
328 /* No header extension */
329 tmp = 0;
330 CopySendInt32(cstate, tmp);
331}
332
333/*
334 * Implementation of the outfunc callback for binary format. Assign
335 * the binary output function to the given *finfo.
336 */
337static void
339{
340 Oid func_oid;
341 bool is_varlena;
342
343 /* Set output function for an attribute */
344 getTypeBinaryOutputInfo(atttypid, &func_oid, &is_varlena);
345 fmgr_info(func_oid, finfo);
346}
347
348/* Implementation of the per-row callback for binary format */
349static void
351{
352 FmgrInfo *out_functions = cstate->out_functions;
353
354 /* Binary per-tuple header */
355 CopySendInt16(cstate, list_length(cstate->attnumlist));
356
358 {
359 Datum value = slot->tts_values[attnum - 1];
360 bool isnull = slot->tts_isnull[attnum - 1];
361
362 if (isnull)
363 {
364 CopySendInt32(cstate, -1);
365 }
366 else
367 {
368 bytea *outputbytes;
369
370 outputbytes = SendFunctionCall(&out_functions[attnum - 1],
371 value);
372 CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
373 CopySendData(cstate, VARDATA(outputbytes),
374 VARSIZE(outputbytes) - VARHDRSZ);
375 }
376 }
377
378 CopySendEndOfRow(cstate);
379}
380
381/* Implementation of the end callback for binary format */
382static void
384{
385 /* Generate trailer for a binary copy */
386 CopySendInt16(cstate, -1);
387 /* Need to flush out the trailer */
388 CopySendEndOfRow(cstate);
389}
390
391/*
392 * Send copy start/stop messages for frontend copies. These have changed
393 * in past protocol redesigns.
394 */
395static void
397{
399 int natts = list_length(cstate->attnumlist);
400 int16 format = (cstate->opts.binary ? 1 : 0);
401 int i;
402
404 pq_sendbyte(&buf, format); /* overall format */
405 pq_sendint16(&buf, natts);
406 for (i = 0; i < natts; i++)
407 pq_sendint16(&buf, format); /* per-column formats */
409 cstate->copy_dest = COPY_FRONTEND;
410}
411
412static void
414{
415 /* Shouldn't have any unsent data */
416 Assert(cstate->fe_msgbuf->len == 0);
417 /* Send Copy Done message */
419}
420
421/*----------
422 * CopySendData sends output data to the destination (file or frontend)
423 * CopySendString does the same for null-terminated strings
424 * CopySendChar does the same for single characters
425 * CopySendEndOfRow does the appropriate thing at end of each data row
426 * (data is not actually flushed except by CopySendEndOfRow)
427 *
428 * NB: no data conversion is applied by these functions
429 *----------
430 */
431static void
432CopySendData(CopyToState cstate, const void *databuf, int datasize)
433{
434 appendBinaryStringInfo(cstate->fe_msgbuf, databuf, datasize);
435}
436
437static void
438CopySendString(CopyToState cstate, const char *str)
439{
440 appendBinaryStringInfo(cstate->fe_msgbuf, str, strlen(str));
441}
442
443static void
445{
447}
448
449static void
451{
452 StringInfo fe_msgbuf = cstate->fe_msgbuf;
453
454 switch (cstate->copy_dest)
455 {
456 case COPY_FILE:
457 if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
458 cstate->copy_file) != 1 ||
459 ferror(cstate->copy_file))
460 {
461 if (cstate->is_program)
462 {
463 if (errno == EPIPE)
464 {
465 /*
466 * The pipe will be closed automatically on error at
467 * the end of transaction, but we might get a better
468 * error message from the subprocess' exit code than
469 * just "Broken Pipe"
470 */
471 ClosePipeToProgram(cstate);
472
473 /*
474 * If ClosePipeToProgram() didn't throw an error, the
475 * program terminated normally, but closed the pipe
476 * first. Restore errno, and throw an error.
477 */
478 errno = EPIPE;
479 }
482 errmsg("could not write to COPY program: %m")));
483 }
484 else
487 errmsg("could not write to COPY file: %m")));
488 }
489 break;
490 case COPY_FRONTEND:
491 /* Dump the accumulated row as one CopyData message */
492 (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
493 break;
494 case COPY_CALLBACK:
495 cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
496 break;
497 }
498
499 /* Update the progress */
500 cstate->bytes_processed += fe_msgbuf->len;
502
503 resetStringInfo(fe_msgbuf);
504}
505
506/*
507 * Wrapper function of CopySendEndOfRow for text and CSV formats. Sends the
508 * line termination and do common appropriate things for the end of row.
509 */
510static inline void
512{
513 switch (cstate->copy_dest)
514 {
515 case COPY_FILE:
516 /* Default line termination depends on platform */
517#ifndef WIN32
518 CopySendChar(cstate, '\n');
519#else
520 CopySendString(cstate, "\r\n");
521#endif
522 break;
523 case COPY_FRONTEND:
524 /* The FE/BE protocol uses \n as newline for all platforms */
525 CopySendChar(cstate, '\n');
526 break;
527 default:
528 break;
529 }
530
531 /* Now take the actions related to the end of a row */
532 CopySendEndOfRow(cstate);
533}
534
535/*
536 * These functions do apply some data conversion
537 */
538
539/*
540 * CopySendInt32 sends an int32 in network byte order
541 */
542static inline void
544{
545 uint32 buf;
546
547 buf = pg_hton32((uint32) val);
548 CopySendData(cstate, &buf, sizeof(buf));
549}
550
551/*
552 * CopySendInt16 sends an int16 in network byte order
553 */
554static inline void
556{
557 uint16 buf;
558
559 buf = pg_hton16((uint16) val);
560 CopySendData(cstate, &buf, sizeof(buf));
561}
562
563/*
564 * Closes the pipe to an external program, checking the pclose() return code.
565 */
566static void
568{
569 int pclose_rc;
570
571 Assert(cstate->is_program);
572
573 pclose_rc = ClosePipeStream(cstate->copy_file);
574 if (pclose_rc == -1)
577 errmsg("could not close pipe to external command: %m")));
578 else if (pclose_rc != 0)
579 {
581 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
582 errmsg("program \"%s\" failed",
583 cstate->filename),
584 errdetail_internal("%s", wait_result_to_str(pclose_rc))));
585 }
586}
587
588/*
589 * Release resources allocated in a cstate for COPY TO.
590 */
591static void
593{
594 if (cstate->is_program)
595 {
596 ClosePipeToProgram(cstate);
597 }
598 else
599 {
600 if (cstate->filename != NULL && FreeFile(cstate->copy_file))
603 errmsg("could not close file \"%s\": %m",
604 cstate->filename)));
605 }
606
608
610
611 if (cstate->partitions)
612 list_free(cstate->partitions);
613
614 pfree(cstate);
615}
616
617/*
618 * Setup CopyToState to read tuples from a table or a query for COPY TO.
619 *
620 * 'rel': Relation to be copied
621 * 'raw_query': Query whose results are to be copied
622 * 'queryRelId': OID of base relation to convert to a query (for RLS)
623 * 'filename': Name of server-local file to write, NULL for STDOUT
624 * 'is_program': true if 'filename' is program to execute
625 * 'data_dest_cb': Callback that processes the output data
626 * 'attnamelist': List of char *, columns to include. NIL selects all cols.
627 * 'options': List of DefElem. See copy_opt_item in gram.y for selections.
628 *
629 * Returns a CopyToState, to be passed to DoCopyTo() and related functions.
630 */
633 Relation rel,
634 RawStmt *raw_query,
635 Oid queryRelId,
636 const char *filename,
637 bool is_program,
638 copy_data_dest_cb data_dest_cb,
639 List *attnamelist,
640 List *options)
641{
642 CopyToState cstate;
643 bool pipe = (filename == NULL && data_dest_cb == NULL);
644 TupleDesc tupDesc;
645 int num_phys_attrs;
646 MemoryContext oldcontext;
647 const int progress_cols[] = {
650 };
651 int64 progress_vals[] = {
653 0
654 };
655 List *children = NIL;
656
657 if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
658 {
659 if (rel->rd_rel->relkind == RELKIND_VIEW)
661 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
662 errmsg("cannot copy from view \"%s\"",
664 errhint("Try the COPY (SELECT ...) TO variant.")));
665 else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
666 {
667 if (!RelationIsPopulated(rel))
669 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
670 errmsg("cannot copy from unpopulated materialized view \"%s\"",
672 errhint("Use the REFRESH MATERIALIZED VIEW command."));
673 }
674 else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
676 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
677 errmsg("cannot copy from foreign table \"%s\"",
679 errhint("Try the COPY (SELECT ...) TO variant.")));
680 else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
682 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
683 errmsg("cannot copy from sequence \"%s\"",
685 else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
686 {
687 /*
688 * Collect OIDs of relation containing data, so that later
689 * DoCopyTo can copy the data from them.
690 */
692
693 foreach_oid(child, children)
694 {
695 char relkind = get_rel_relkind(child);
696
697 if (relkind == RELKIND_FOREIGN_TABLE)
698 {
699 char *relation_name = get_rel_name(child);
700
702 errcode(ERRCODE_WRONG_OBJECT_TYPE),
703 errmsg("cannot copy from foreign table \"%s\"", relation_name),
704 errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"",
705 relation_name, RelationGetRelationName(rel)),
706 errhint("Try the COPY (SELECT ...) TO variant."));
707 }
708
709 /* Exclude tables with no data */
710 if (RELKIND_HAS_PARTITIONS(relkind))
711 children = foreach_delete_current(children, child);
712 }
713 }
714 else
716 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
717 errmsg("cannot copy from non-table relation \"%s\"",
719 }
720
721
722 /* Allocate workspace and zero all fields */
723 cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData));
724
725 /*
726 * We allocate everything used by a cstate in a new memory context. This
727 * avoids memory leaks during repeated use of COPY in a query.
728 */
730 "COPY",
732
733 oldcontext = MemoryContextSwitchTo(cstate->copycontext);
734
735 /* Extract options from the statement node tree */
736 ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options);
737
738 /* Set format routine */
739 cstate->routine = CopyToGetRoutine(&cstate->opts);
740
741 /* Process the source/target relation or query */
742 if (rel)
743 {
744 Assert(!raw_query);
745
746 cstate->rel = rel;
747
748 tupDesc = RelationGetDescr(cstate->rel);
749 cstate->partitions = children;
750 }
751 else
752 {
753 List *rewritten;
754 Query *query;
757
758 cstate->rel = NULL;
759 cstate->partitions = NIL;
760
761 /*
762 * Run parse analysis and rewrite. Note this also acquires sufficient
763 * locks on the source table(s).
764 */
765 rewritten = pg_analyze_and_rewrite_fixedparams(raw_query,
766 pstate->p_sourcetext, NULL, 0,
767 NULL);
768
769 /* check that we got back something we can work with */
770 if (rewritten == NIL)
771 {
773 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
774 errmsg("DO INSTEAD NOTHING rules are not supported for COPY")));
775 }
776 else if (list_length(rewritten) > 1)
777 {
778 ListCell *lc;
779
780 /* examine queries to determine which error message to issue */
781 foreach(lc, rewritten)
782 {
783 Query *q = lfirst_node(Query, lc);
784
785 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
787 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
788 errmsg("conditional DO INSTEAD rules are not supported for COPY")));
789 if (q->querySource == QSRC_NON_INSTEAD_RULE)
791 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
792 errmsg("DO ALSO rules are not supported for COPY")));
793 }
794
796 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
797 errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
798 }
799
800 query = linitial_node(Query, rewritten);
801
802 /* The grammar allows SELECT INTO, but we don't support that */
803 if (query->utilityStmt != NULL &&
806 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
807 errmsg("COPY (SELECT INTO) is not supported")));
808
809 /* The only other utility command we could see is NOTIFY */
810 if (query->utilityStmt != NULL)
812 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
813 errmsg("COPY query must not be a utility command")));
814
815 /*
816 * Similarly the grammar doesn't enforce the presence of a RETURNING
817 * clause, but this is required here.
818 */
819 if (query->commandType != CMD_SELECT &&
820 query->returningList == NIL)
821 {
822 Assert(query->commandType == CMD_INSERT ||
823 query->commandType == CMD_UPDATE ||
824 query->commandType == CMD_DELETE ||
825 query->commandType == CMD_MERGE);
826
828 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
829 errmsg("COPY query must have a RETURNING clause")));
830 }
831
832 /* plan the query */
833 plan = pg_plan_query(query, pstate->p_sourcetext,
834 CURSOR_OPT_PARALLEL_OK, NULL, NULL);
835
836 /*
837 * With row-level security and a user using "COPY relation TO", we
838 * have to convert the "COPY relation TO" to a query-based COPY (eg:
839 * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
840 * add in any RLS clauses.
841 *
842 * When this happens, we are passed in the relid of the originally
843 * found relation (which we have locked). As the planner will look up
844 * the relation again, we double-check here to make sure it found the
845 * same one that we have locked.
846 */
847 if (queryRelId != InvalidOid)
848 {
849 /*
850 * Note that with RLS involved there may be multiple relations,
851 * and while the one we need is almost certainly first, we don't
852 * make any guarantees of that in the planner, so check the whole
853 * list and make sure we find the original relation.
854 */
855 if (!list_member_oid(plan->relationOids, queryRelId))
857 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
858 errmsg("relation referenced by COPY statement has changed")));
859 }
860
861 /*
862 * Use a snapshot with an updated command ID to ensure this query sees
863 * results of any previously executed queries.
864 */
867
868 /* Create dest receiver for COPY OUT */
870 ((DR_copy *) dest)->cstate = cstate;
871
872 /* Create a QueryDesc requesting no output */
873 cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
876 dest, NULL, NULL, 0);
877
878 /*
879 * Call ExecutorStart to prepare the plan for execution.
880 *
881 * ExecutorStart computes a result tupdesc for us
882 */
883 ExecutorStart(cstate->queryDesc, 0);
884
885 tupDesc = cstate->queryDesc->tupDesc;
886 }
887
888 /* Generate or convert list of attributes to process */
889 cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
890
891 num_phys_attrs = tupDesc->natts;
892
893 /* Convert FORCE_QUOTE name list to per-column flags, check validity */
894 cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
895 if (cstate->opts.force_quote_all)
896 {
897 MemSet(cstate->opts.force_quote_flags, true, num_phys_attrs * sizeof(bool));
898 }
899 else if (cstate->opts.force_quote)
900 {
901 List *attnums;
902 ListCell *cur;
903
904 attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote);
905
906 foreach(cur, attnums)
907 {
908 int attnum = lfirst_int(cur);
909 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
910
911 if (!list_member_int(cstate->attnumlist, attnum))
913 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
914 /*- translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL */
915 errmsg("%s column \"%s\" not referenced by COPY",
916 "FORCE_QUOTE", NameStr(attr->attname))));
917 cstate->opts.force_quote_flags[attnum - 1] = true;
918 }
919 }
920
921 /* Use client encoding when ENCODING option is not specified. */
922 if (cstate->opts.file_encoding < 0)
924 else
925 cstate->file_encoding = cstate->opts.file_encoding;
926
927 /*
928 * Set up encoding conversion info if the file and server encodings differ
929 * (see also pg_server_to_any).
930 */
931 if (cstate->file_encoding == GetDatabaseEncoding() ||
932 cstate->file_encoding == PG_SQL_ASCII)
933 cstate->need_transcoding = false;
934 else
935 cstate->need_transcoding = true;
936
937 /* See Multibyte encoding comment above */
939
940 cstate->copy_dest = COPY_FILE; /* default */
941
942 if (data_dest_cb)
943 {
944 progress_vals[1] = PROGRESS_COPY_TYPE_CALLBACK;
945 cstate->copy_dest = COPY_CALLBACK;
946 cstate->data_dest_cb = data_dest_cb;
947 }
948 else if (pipe)
949 {
950 progress_vals[1] = PROGRESS_COPY_TYPE_PIPE;
951
952 Assert(!is_program); /* the grammar does not allow this */
954 cstate->copy_file = stdout;
955 }
956 else
957 {
958 cstate->filename = pstrdup(filename);
959 cstate->is_program = is_program;
960
961 if (is_program)
962 {
963 progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM;
964 cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W);
965 if (cstate->copy_file == NULL)
968 errmsg("could not execute command \"%s\": %m",
969 cstate->filename)));
970 }
971 else
972 {
973 mode_t oumask; /* Pre-existing umask value */
974 struct stat st;
975
976 progress_vals[1] = PROGRESS_COPY_TYPE_FILE;
977
978 /*
979 * Prevent write to relative path ... too easy to shoot oneself in
980 * the foot by overwriting a database file ...
981 */
984 (errcode(ERRCODE_INVALID_NAME),
985 errmsg("relative path not allowed for COPY to file")));
986
987 oumask = umask(S_IWGRP | S_IWOTH);
988 PG_TRY();
989 {
990 cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W);
991 }
992 PG_FINALLY();
993 {
994 umask(oumask);
995 }
996 PG_END_TRY();
997 if (cstate->copy_file == NULL)
998 {
999 /* copy errno because ereport subfunctions might change it */
1000 int save_errno = errno;
1001
1002 ereport(ERROR,
1004 errmsg("could not open file \"%s\" for writing: %m",
1005 cstate->filename),
1006 (save_errno == ENOENT || save_errno == EACCES) ?
1007 errhint("COPY TO instructs the PostgreSQL server process to write a file. "
1008 "You may want a client-side facility such as psql's \\copy.") : 0));
1009 }
1010
1011 if (fstat(fileno(cstate->copy_file), &st))
1012 ereport(ERROR,
1014 errmsg("could not stat file \"%s\": %m",
1015 cstate->filename)));
1016
1017 if (S_ISDIR(st.st_mode))
1018 ereport(ERROR,
1019 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1020 errmsg("\"%s\" is a directory", cstate->filename)));
1021 }
1022 }
1023
1024 /* initialize progress */
1026 cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1027 pgstat_progress_update_multi_param(2, progress_cols, progress_vals);
1028
1029 cstate->bytes_processed = 0;
1030
1031 MemoryContextSwitchTo(oldcontext);
1032
1033 return cstate;
1034}
1035
1036/*
1037 * Clean up storage and release resources for COPY TO.
1038 */
1039void
1041{
1042 if (cstate->queryDesc != NULL)
1043 {
1044 /* Close down the query and free resources. */
1045 ExecutorFinish(cstate->queryDesc);
1046 ExecutorEnd(cstate->queryDesc);
1047 FreeQueryDesc(cstate->queryDesc);
1049 }
1050
1051 /* Clean up storage */
1052 EndCopy(cstate);
1053}
1054
1055/*
1056 * Copy from relation or query TO file.
1057 *
1058 * Returns the number of rows processed.
1059 */
1060uint64
1062{
1063 bool pipe = (cstate->filename == NULL && cstate->data_dest_cb == NULL);
1064 bool fe_copy = (pipe && whereToSendOutput == DestRemote);
1065 TupleDesc tupDesc;
1066 int num_phys_attrs;
1067 ListCell *cur;
1068 uint64 processed = 0;
1069
1070 if (fe_copy)
1071 SendCopyBegin(cstate);
1072
1073 if (cstate->rel)
1074 tupDesc = RelationGetDescr(cstate->rel);
1075 else
1076 tupDesc = cstate->queryDesc->tupDesc;
1077 num_phys_attrs = tupDesc->natts;
1078 cstate->opts.null_print_client = cstate->opts.null_print; /* default */
1079
1080 /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1081 cstate->fe_msgbuf = makeStringInfo();
1082
1083 /* Get info about the columns we need to process. */
1084 cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1085 foreach(cur, cstate->attnumlist)
1086 {
1087 int attnum = lfirst_int(cur);
1088 Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1089
1090 cstate->routine->CopyToOutFunc(cstate, attr->atttypid,
1091 &cstate->out_functions[attnum - 1]);
1092 }
1093
1094 /*
1095 * Create a temporary memory context that we can reset once per row to
1096 * recover palloc'd memory. This avoids any problems with leaks inside
1097 * datatype output routines, and should be faster than retail pfree's
1098 * anyway. (We don't need a whole econtext as CopyFrom does.)
1099 */
1101 "COPY TO",
1103
1104 cstate->routine->CopyToStart(cstate, tupDesc);
1105
1106 if (cstate->rel)
1107 {
1108 /*
1109 * If COPY TO source table is a partitioned table, then open each
1110 * partition and process each individual partition.
1111 */
1112 if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1113 {
1114 foreach_oid(child, cstate->partitions)
1115 {
1116 Relation scan_rel;
1117
1118 /* We already got the lock in BeginCopyTo */
1119 scan_rel = table_open(child, NoLock);
1120 CopyRelationTo(cstate, scan_rel, cstate->rel, &processed);
1121 table_close(scan_rel, NoLock);
1122 }
1123 }
1124 else
1125 CopyRelationTo(cstate, cstate->rel, NULL, &processed);
1126 }
1127 else
1128 {
1129 /* run the plan --- the dest receiver will send tuples */
1131 processed = ((DR_copy *) cstate->queryDesc->dest)->processed;
1132 }
1133
1134 cstate->routine->CopyToEnd(cstate);
1135
1137
1138 if (fe_copy)
1139 SendCopyEnd(cstate);
1140
1141 return processed;
1142}
1143
1144/*
1145 * Scans a single table and exports its rows to the COPY destination.
1146 *
1147 * root_rel can be set to the root table of rel if rel is a partition
1148 * table so that we can send tuples in root_rel's rowtype, which might
1149 * differ from individual partitions.
1150*/
1151static void
1152CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
1153{
1154 TupleTableSlot *slot;
1155 TableScanDesc scandesc;
1156 AttrMap *map = NULL;
1157 TupleTableSlot *root_slot = NULL;
1158
1159 scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
1160 slot = table_slot_create(rel, NULL);
1161
1162 /*
1163 * If we are exporting partition data here, we check if converting tuples
1164 * to the root table's rowtype, because a partition might have column
1165 * order different than its root table.
1166 */
1167 if (root_rel != NULL)
1168 {
1169 root_slot = table_slot_create(root_rel, NULL);
1171 RelationGetDescr(rel),
1172 false);
1173 }
1174
1175 while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot))
1176 {
1177 TupleTableSlot *copyslot;
1178
1180
1181 if (map != NULL)
1182 copyslot = execute_attr_map_slot(map, slot, root_slot);
1183 else
1184 {
1185 /* Deconstruct the tuple */
1186 slot_getallattrs(slot);
1187 copyslot = slot;
1188 }
1189
1190 /* Format and send the data */
1191 CopyOneRowTo(cstate, copyslot);
1192
1193 /*
1194 * Increment the number of processed tuples, and report the progress.
1195 */
1197 ++(*processed));
1198 }
1199
1201
1202 if (root_slot != NULL)
1204
1205 if (map != NULL)
1206 free_attrmap(map);
1207
1208 table_endscan(scandesc);
1209}
1210
1211/*
1212 * Emit one row during DoCopyTo().
1213 */
1214static inline void
1216{
1217 MemoryContext oldcontext;
1218
1220 oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
1221
1222 /* Make sure the tuple is fully deconstructed */
1223 slot_getallattrs(slot);
1224
1225 cstate->routine->CopyToOneRow(cstate, slot);
1226
1227 MemoryContextSwitchTo(oldcontext);
1228}
1229
1230/*
1231 * Send text representation of one attribute, with conversion and escaping
1232 */
1233#define DUMPSOFAR() \
1234 do { \
1235 if (ptr > start) \
1236 CopySendData(cstate, start, ptr - start); \
1237 } while (0)
1238
1239static void
1240CopyAttributeOutText(CopyToState cstate, const char *string)
1241{
1242 const char *ptr;
1243 const char *start;
1244 char c;
1245 char delimc = cstate->opts.delim[0];
1246
1247 if (cstate->need_transcoding)
1248 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1249 else
1250 ptr = string;
1251
1252 /*
1253 * We have to grovel through the string searching for control characters
1254 * and instances of the delimiter character. In most cases, though, these
1255 * are infrequent. To avoid overhead from calling CopySendData once per
1256 * character, we dump out all characters between escaped characters in a
1257 * single call. The loop invariant is that the data from "start" to "ptr"
1258 * can be sent literally, but hasn't yet been.
1259 *
1260 * We can skip pg_encoding_mblen() overhead when encoding is safe, because
1261 * in valid backend encodings, extra bytes of a multibyte character never
1262 * look like ASCII. This loop is sufficiently performance-critical that
1263 * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out
1264 * of the normal safe-encoding path.
1265 */
1266 if (cstate->encoding_embeds_ascii)
1267 {
1268 start = ptr;
1269 while ((c = *ptr) != '\0')
1270 {
1271 if ((unsigned char) c < (unsigned char) 0x20)
1272 {
1273 /*
1274 * \r and \n must be escaped, the others are traditional. We
1275 * prefer to dump these using the C-like notation, rather than
1276 * a backslash and the literal character, because it makes the
1277 * dump file a bit more proof against Microsoftish data
1278 * mangling.
1279 */
1280 switch (c)
1281 {
1282 case '\b':
1283 c = 'b';
1284 break;
1285 case '\f':
1286 c = 'f';
1287 break;
1288 case '\n':
1289 c = 'n';
1290 break;
1291 case '\r':
1292 c = 'r';
1293 break;
1294 case '\t':
1295 c = 't';
1296 break;
1297 case '\v':
1298 c = 'v';
1299 break;
1300 default:
1301 /* If it's the delimiter, must backslash it */
1302 if (c == delimc)
1303 break;
1304 /* All ASCII control chars are length 1 */
1305 ptr++;
1306 continue; /* fall to end of loop */
1307 }
1308 /* if we get here, we need to convert the control char */
1309 DUMPSOFAR();
1310 CopySendChar(cstate, '\\');
1311 CopySendChar(cstate, c);
1312 start = ++ptr; /* do not include char in next run */
1313 }
1314 else if (c == '\\' || c == delimc)
1315 {
1316 DUMPSOFAR();
1317 CopySendChar(cstate, '\\');
1318 start = ptr++; /* we include char in next run */
1319 }
1320 else if (IS_HIGHBIT_SET(c))
1321 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1322 else
1323 ptr++;
1324 }
1325 }
1326 else
1327 {
1328 start = ptr;
1329 while ((c = *ptr) != '\0')
1330 {
1331 if ((unsigned char) c < (unsigned char) 0x20)
1332 {
1333 /*
1334 * \r and \n must be escaped, the others are traditional. We
1335 * prefer to dump these using the C-like notation, rather than
1336 * a backslash and the literal character, because it makes the
1337 * dump file a bit more proof against Microsoftish data
1338 * mangling.
1339 */
1340 switch (c)
1341 {
1342 case '\b':
1343 c = 'b';
1344 break;
1345 case '\f':
1346 c = 'f';
1347 break;
1348 case '\n':
1349 c = 'n';
1350 break;
1351 case '\r':
1352 c = 'r';
1353 break;
1354 case '\t':
1355 c = 't';
1356 break;
1357 case '\v':
1358 c = 'v';
1359 break;
1360 default:
1361 /* If it's the delimiter, must backslash it */
1362 if (c == delimc)
1363 break;
1364 /* All ASCII control chars are length 1 */
1365 ptr++;
1366 continue; /* fall to end of loop */
1367 }
1368 /* if we get here, we need to convert the control char */
1369 DUMPSOFAR();
1370 CopySendChar(cstate, '\\');
1371 CopySendChar(cstate, c);
1372 start = ++ptr; /* do not include char in next run */
1373 }
1374 else if (c == '\\' || c == delimc)
1375 {
1376 DUMPSOFAR();
1377 CopySendChar(cstate, '\\');
1378 start = ptr++; /* we include char in next run */
1379 }
1380 else
1381 ptr++;
1382 }
1383 }
1384
1385 DUMPSOFAR();
1386}
1387
1388/*
1389 * Send text representation of one attribute, with conversion and
1390 * CSV-style escaping
1391 */
1392static void
1393CopyAttributeOutCSV(CopyToState cstate, const char *string,
1394 bool use_quote)
1395{
1396 const char *ptr;
1397 const char *start;
1398 char c;
1399 char delimc = cstate->opts.delim[0];
1400 char quotec = cstate->opts.quote[0];
1401 char escapec = cstate->opts.escape[0];
1402 bool single_attr = (list_length(cstate->attnumlist) == 1);
1403
1404 /* force quoting if it matches null_print (before conversion!) */
1405 if (!use_quote && strcmp(string, cstate->opts.null_print) == 0)
1406 use_quote = true;
1407
1408 if (cstate->need_transcoding)
1409 ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding);
1410 else
1411 ptr = string;
1412
1413 /*
1414 * Make a preliminary pass to discover if it needs quoting
1415 */
1416 if (!use_quote)
1417 {
1418 /*
1419 * Quote '\.' if it appears alone on a line, so that it will not be
1420 * interpreted as an end-of-data marker. (PG 18 and up will not
1421 * interpret '\.' in CSV that way, except in embedded-in-SQL data; but
1422 * we want the data to be loadable by older versions too. Also, this
1423 * avoids breaking clients that are still using PQgetline().)
1424 */
1425 if (single_attr && strcmp(ptr, "\\.") == 0)
1426 use_quote = true;
1427 else
1428 {
1429 const char *tptr = ptr;
1430
1431 while ((c = *tptr) != '\0')
1432 {
1433 if (c == delimc || c == quotec || c == '\n' || c == '\r')
1434 {
1435 use_quote = true;
1436 break;
1437 }
1438 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1439 tptr += pg_encoding_mblen(cstate->file_encoding, tptr);
1440 else
1441 tptr++;
1442 }
1443 }
1444 }
1445
1446 if (use_quote)
1447 {
1448 CopySendChar(cstate, quotec);
1449
1450 /*
1451 * We adopt the same optimization strategy as in CopyAttributeOutText
1452 */
1453 start = ptr;
1454 while ((c = *ptr) != '\0')
1455 {
1456 if (c == quotec || c == escapec)
1457 {
1458 DUMPSOFAR();
1459 CopySendChar(cstate, escapec);
1460 start = ptr; /* we include char in next run */
1461 }
1462 if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii)
1463 ptr += pg_encoding_mblen(cstate->file_encoding, ptr);
1464 else
1465 ptr++;
1466 }
1467 DUMPSOFAR();
1468
1469 CopySendChar(cstate, quotec);
1470 }
1471 else
1472 {
1473 /* If it doesn't need quoting, we can just dump it as-is */
1474 CopySendString(cstate, ptr);
1475 }
1476}
1477
1478/*
1479 * copy_dest_startup --- executor startup
1480 */
1481static void
1482copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
1483{
1484 /* no-op */
1485}
1486
1487/*
1488 * copy_dest_receive --- receive one tuple
1489 */
1490static bool
1492{
1493 DR_copy *myState = (DR_copy *) self;
1494 CopyToState cstate = myState->cstate;
1495
1496 /* Send the data */
1497 CopyOneRowTo(cstate, slot);
1498
1499 /* Increment the number of processed tuples, and report the progress */
1501 ++myState->processed);
1502
1503 return true;
1504}
1505
1506/*
1507 * copy_dest_shutdown --- executor end
1508 */
1509static void
1511{
1512 /* no-op */
1513}
1514
1515/*
1516 * copy_dest_destroy --- release DestReceiver object
1517 */
1518static void
1520{
1521 pfree(self);
1522}
1523
1524/*
1525 * CreateCopyDestReceiver -- create a suitable DestReceiver object
1526 */
1529{
1530 DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
1531
1536 self->pub.mydest = DestCopyOut;
1537
1538 self->cstate = NULL; /* will be set later */
1539 self->processed = 0;
1540
1541 return (DestReceiver *) self;
1542}
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:998
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition: copy.c:549
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:756
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1145
#define VARHDRSZ
Definition: c.h:702
int64_t int64
Definition: c.h:540
#define pg_attribute_always_inline
Definition: c.h:274
int16_t int16
Definition: c.h:538
int32_t int32
Definition: c.h:539
uint64_t uint64
Definition: c.h:544
uint16_t uint16
Definition: c.h:542
uint32_t uint32
Definition: c.h:543
#define PG_BINARY_W
Definition: c.h:1266
#define MemSet(start, val, len)
Definition: c.h:1024
static void CopyToBinaryOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition: copyto.c:338
static void CopyToBinaryOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:350
static void CopySendInt32(CopyToState cstate, int32 val)
Definition: copyto.c:543
static void ClosePipeToProgram(CopyToState cstate)
Definition: copyto.c:567
static const CopyToRoutine CopyToRoutineCSV
Definition: copyto.c:165
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copyto.c:1491
static void CopyAttributeOutCSV(CopyToState cstate, const char *string, bool use_quote)
Definition: copyto.c:1393
uint64 DoCopyTo(CopyToState cstate)
Definition: copyto.c:1061
static void CopyToTextLikeEnd(CopyToState cstate)
Definition: copyto.c:309
static void CopyAttributeOutText(CopyToState cstate, const char *string)
Definition: copyto.c:1240
struct CopyToStateData CopyToStateData
#define DUMPSOFAR()
Definition: copyto.c:1233
static const CopyToRoutine CopyToRoutineText
Definition: copyto.c:157
static void CopySendInt16(CopyToState cstate, int16 val)
Definition: copyto.c:555
static void CopySendData(CopyToState cstate, const void *databuf, int datasize)
Definition: copyto.c:432
static void CopyToTextOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:250
static void CopySendChar(CopyToState cstate, char c)
Definition: copyto.c:444
DestReceiver * CreateCopyDestReceiver(void)
Definition: copyto.c:1528
static const CopyToRoutine * CopyToGetRoutine(const CopyFormatOptions *opts)
Definition: copyto.c:182
static void CopySendTextLikeEndOfRow(CopyToState cstate)
Definition: copyto.c:511
static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed)
Definition: copyto.c:1152
static void EndCopy(CopyToState cstate)
Definition: copyto.c:592
static void copy_dest_destroy(DestReceiver *self)
Definition: copyto.c:1519
CopyDest
Definition: copyto.c:46
@ COPY_FILE
Definition: copyto.c:47
@ COPY_CALLBACK
Definition: copyto.c:49
@ COPY_FRONTEND
Definition: copyto.c:48
static void CopyToTextLikeOutFunc(CopyToState cstate, Oid atttypid, FmgrInfo *finfo)
Definition: copyto.c:238
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:632
static void copy_dest_shutdown(DestReceiver *self)
Definition: copyto.c:1510
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copyto.c:1482
static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc)
Definition: copyto.c:195
static void SendCopyBegin(CopyToState cstate)
Definition: copyto.c:396
static void SendCopyEnd(CopyToState cstate)
Definition: copyto.c:413
static void CopySendEndOfRow(CopyToState cstate)
Definition: copyto.c:450
static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:1215
static void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv)
Definition: copyto.c:269
static void CopySendString(CopyToState cstate, const char *str)
Definition: copyto.c:438
static void CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot)
Definition: copyto.c:257
static const char BinarySignature[11]
Definition: copyto.c:112
void EndCopyTo(CopyToState cstate)
Definition: copyto.c:1040
static void CopyToBinaryStart(CopyToState cstate, TupleDesc tupDesc)
Definition: copyto.c:319
static const CopyToRoutine CopyToRoutineBinary
Definition: copyto.c:173
static void CopyToBinaryEnd(CopyToState cstate)
Definition: copyto.c:383
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 errdetail_internal(const char *fmt,...)
Definition: elog.c:1243
int errcode_for_file_access(void)
Definition: elog.c:886
int errdetail(const char *fmt,...)
Definition: elog.c:1216
int errhint(const char *fmt,...)
Definition: elog.c:1330
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define ERROR
Definition: elog.h:39
#define PG_FINALLY(...)
Definition: elog.h:389
#define ereport(elevel,...)
Definition: elog.h:150
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:466
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:406
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:122
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition: execMain.c:297
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1443
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2744
int ClosePipeStream(FILE *file)
Definition: fd.c:3052
int FreeFile(FILE *file)
Definition: fd.c:2840
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2641
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:128
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1744
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
Assert(PointerIsAligned(start, uint64))
return str start
const char * str
void(* copy_data_dest_cb)(void *data, int len)
Definition: copy.h:95
#define COPY_HEADER_TRUE
Definition: copy.h:28
long val
Definition: informix.c:689
static struct @171 value
int i
Definition: isn.c:77
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:49
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:2095
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:3140
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:3074
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2170
int GetDatabaseEncoding(void)
Definition: mbutils.c:1262
int pg_get_client_encoding(void)
Definition: mbutils.c:337
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:750
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:400
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc0(Size size)
Definition: mcxt.c:1395
void * palloc(Size size)
Definition: mcxt.c:1365
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
@ CMD_MERGE
Definition: nodes.h:279
@ CMD_INSERT
Definition: nodes.h:277
@ CMD_DELETE
Definition: nodes.h:278
@ CMD_UPDATE
Definition: nodes.h:276
@ CMD_SELECT
Definition: nodes.h:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
@ QSRC_NON_INSTEAD_RULE
Definition: parsenodes.h:40
@ QSRC_QUAL_INSTEAD_RULE
Definition: parsenodes.h:39
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:3396
static AmcheckOptions opts
Definition: pg_amcheck.c:112
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
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)
Definition: pg_inherits.c:255
#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 lfirst_int(lc)
Definition: pg_list.h:173
#define foreach_delete_current(lst, var_or_cell)
Definition: pg_list.h:391
#define foreach_oid(var, lst)
Definition: pg_list.h:471
#define foreach_int(var, lst)
Definition: pg_list.h:470
#define plan(x)
Definition: pg_regress.c:161
static char * buf
Definition: pg_test_fsync.c:72
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition: pg_wchar.h:284
#define is_absolute_path(filename)
Definition: port.h:104
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition: postgres.c:887
CommandDest whereToSendOutput
Definition: postgres.c:92
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:670
uint64_t Datum
Definition: postgres.h:70
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:388
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:106
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
char string[11]
Definition: preproc-type.c:52
#define PROGRESS_COPY_COMMAND
Definition: progress.h:151
#define PROGRESS_COPY_TYPE_FILE
Definition: progress.h:160
#define PROGRESS_COPY_BYTES_PROCESSED
Definition: progress.h:147
#define PROGRESS_COPY_COMMAND_TO
Definition: progress.h:157
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition: progress.h:149
#define PROGRESS_COPY_TYPE
Definition: progress.h:152
#define PROGRESS_COPY_TYPE_PROGRAM
Definition: progress.h:161
#define PROGRESS_COPY_TYPE_CALLBACK
Definition: progress.h:163
#define PROGRESS_COPY_TYPE_PIPE
Definition: progress.h:162
#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:515
#define RelationGetDescr(relation)
Definition: rel.h:541
#define RelationGetRelationName(relation)
Definition: rel.h:549
#define RelationIsPopulated(relation)
Definition: rel.h:687
@ 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
Definition: attmap.h:35
int header_line
Definition: copy.h:64
bool force_quote_all
Definition: copy.h:75
bool binary
Definition: copy.h:61
int null_print_len
Definition: copy.h:67
char * quote
Definition: copy.h:72
List * force_quote
Definition: copy.h:74
char * escape
Definition: copy.h:73
char * null_print
Definition: copy.h:66
char * delim
Definition: copy.h:71
bool * force_quote_flags
Definition: copy.h:76
char * null_print_client
Definition: copy.h:68
bool csv_mode
Definition: copy.h:63
int file_encoding
Definition: copy.h:59
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:98
MemoryContext copycontext
Definition: copyto.c:96
Node * whereClause
Definition: copyto.c:90
Relation rel
Definition: copyto.c:82
const CopyToRoutine * routine
Definition: copyto.c:70
copy_data_dest_cb data_dest_cb
Definition: copyto.c:87
bool encoding_embeds_ascii
Definition: copyto.c:79
CopyDest copy_dest
Definition: copyto.c:73
bool need_transcoding
Definition: copyto.c:78
bool is_program
Definition: copyto.c:86
FILE * copy_file
Definition: copyto.c:74
int file_encoding
Definition: copyto.c:77
MemoryContext rowcontext
Definition: copyto.c:99
CopyFormatOptions opts
Definition: copyto.c:89
uint64 bytes_processed
Definition: copyto.c:100
StringInfo fe_msgbuf
Definition: copyto.c:75
char * filename
Definition: copyto.c:85
List * attnumlist
Definition: copyto.c:84
QueryDesc * queryDesc
Definition: copyto.c:83
List * partitions
Definition: copyto.c:91
CopyToState cstate
Definition: copyto.c:107
DestReceiver pub
Definition: copyto.c:106
uint64 processed
Definition: copyto.c:108
Definition: fmgr.h:57
Definition: pg_list.h:54
Definition: nodes.h:135
const char * p_sourcetext
Definition: parse_node.h:195
DestReceiver * dest
Definition: execdesc.h:41
TupleDesc tupDesc
Definition: execdesc.h:47
List * returningList
Definition: parsenodes.h:214
CmdType commandType
Definition: parsenodes.h:121
Node * utilityStmt
Definition: parsenodes.h:141
Form_pg_class rd_rel
Definition: rel.h:111
bool * tts_isnull
Definition: tuptable.h:126
Datum * tts_values
Definition: tuptable.h:124
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:697
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
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:985
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1020
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key)
Definition: tableam.h:876
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:193
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:371
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
int pg_encoding_mblen(int encoding, const char *mbstr)
Definition: wchar.c:2135
#define S_IWOTH
Definition: win32_port.h:306
#define S_ISDIR(m)
Definition: win32_port.h:315
#define fstat
Definition: win32_port.h:273
#define S_IWGRP
Definition: win32_port.h:294