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