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