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