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