PostgreSQL Source Code  git master
copyfrom.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * copyfrom.c
4  * COPY <table> FROM file/program/client
5  *
6  * This file contains routines needed to efficiently load tuples into a
7  * table. That includes looking up the correct partition, firing triggers,
8  * calling the table AM function to insert the data, and updating indexes.
9  * Reading data from the input file or client and parsing it into Datums
10  * is handled in copyfromparse.c.
11  *
12  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  * src/backend/commands/copyfrom.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include <ctype.h>
24 #include <unistd.h>
25 #include <sys/stat.h>
26 
27 #include "access/heapam.h"
28 #include "access/htup_details.h"
29 #include "access/tableam.h"
30 #include "access/xact.h"
31 #include "access/xlog.h"
32 #include "catalog/namespace.h"
33 #include "commands/copy.h"
35 #include "commands/progress.h"
36 #include "commands/trigger.h"
37 #include "executor/execPartition.h"
38 #include "executor/executor.h"
40 #include "executor/tuptable.h"
41 #include "foreign/fdwapi.h"
42 #include "libpq/libpq.h"
43 #include "libpq/pqformat.h"
44 #include "miscadmin.h"
45 #include "optimizer/optimizer.h"
46 #include "pgstat.h"
47 #include "rewrite/rewriteHandler.h"
48 #include "storage/fd.h"
49 #include "tcop/tcopprot.h"
50 #include "utils/lsyscache.h"
51 #include "utils/memutils.h"
52 #include "utils/portal.h"
53 #include "utils/rel.h"
54 #include "utils/snapmgr.h"
55 
56 /*
57  * No more than this many tuples per CopyMultiInsertBuffer
58  *
59  * Caution: Don't make this too big, as we could end up with this many
60  * CopyMultiInsertBuffer items stored in CopyMultiInsertInfo's
61  * multiInsertBuffers list. Increasing this can cause quadratic growth in
62  * memory requirements during copies into partitioned tables with a large
63  * number of partitions.
64  */
65 #define MAX_BUFFERED_TUPLES 1000
66 
67 /*
68  * Flush buffers if there are >= this many bytes, as counted by the input
69  * size, of tuples stored.
70  */
71 #define MAX_BUFFERED_BYTES 65535
72 
73 /* Trim the list of buffers back down to this number after flushing */
74 #define MAX_PARTITION_BUFFERS 32
75 
76 /* Stores multi-insert data related to a single relation in CopyFrom. */
77 typedef struct CopyMultiInsertBuffer
78 {
79  TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; /* Array to store tuples */
80  ResultRelInfo *resultRelInfo; /* ResultRelInfo for 'relid' */
81  BulkInsertState bistate; /* BulkInsertState for this rel if plain
82  * table; NULL if foreign table */
83  int nused; /* number of 'slots' containing tuples */
84  uint64 linenos[MAX_BUFFERED_TUPLES]; /* Line # of tuple in copy
85  * stream */
87 
88 /*
89  * Stores one or many CopyMultiInsertBuffers and details about the size and
90  * number of tuples which are stored in them. This allows multiple buffers to
91  * exist at once when COPYing into a partitioned table.
92  */
93 typedef struct CopyMultiInsertInfo
94 {
95  List *multiInsertBuffers; /* List of tracked CopyMultiInsertBuffers */
96  int bufferedTuples; /* number of tuples buffered over all buffers */
97  int bufferedBytes; /* number of bytes from all buffered tuples */
98  CopyFromState cstate; /* Copy state for this CopyMultiInsertInfo */
99  EState *estate; /* Executor state used for COPY */
100  CommandId mycid; /* Command Id used for COPY */
101  int ti_options; /* table insert options */
103 
104 
105 /* non-export function prototypes */
106 static char *limit_printout_length(const char *str);
107 
108 static void ClosePipeFromProgram(CopyFromState cstate);
109 
110 /*
111  * error context callback for COPY FROM
112  *
113  * The argument for the error context must be CopyFromState.
114  */
115 void
117 {
118  CopyFromState cstate = (CopyFromState) arg;
119 
120  if (cstate->relname_only)
121  {
122  errcontext("COPY %s",
123  cstate->cur_relname);
124  return;
125  }
126  if (cstate->opts.binary)
127  {
128  /* can't usefully display the data */
129  if (cstate->cur_attname)
130  errcontext("COPY %s, line %llu, column %s",
131  cstate->cur_relname,
132  (unsigned long long) cstate->cur_lineno,
133  cstate->cur_attname);
134  else
135  errcontext("COPY %s, line %llu",
136  cstate->cur_relname,
137  (unsigned long long) cstate->cur_lineno);
138  }
139  else
140  {
141  if (cstate->cur_attname && cstate->cur_attval)
142  {
143  /* error is relevant to a particular column */
144  char *attval;
145 
146  attval = limit_printout_length(cstate->cur_attval);
147  errcontext("COPY %s, line %llu, column %s: \"%s\"",
148  cstate->cur_relname,
149  (unsigned long long) cstate->cur_lineno,
150  cstate->cur_attname,
151  attval);
152  pfree(attval);
153  }
154  else if (cstate->cur_attname)
155  {
156  /* error is relevant to a particular column, value is NULL */
157  errcontext("COPY %s, line %llu, column %s: null input",
158  cstate->cur_relname,
159  (unsigned long long) cstate->cur_lineno,
160  cstate->cur_attname);
161  }
162  else
163  {
164  /*
165  * Error is relevant to a particular line.
166  *
167  * If line_buf still contains the correct line, print it.
168  */
169  if (cstate->line_buf_valid)
170  {
171  char *lineval;
172 
173  lineval = limit_printout_length(cstate->line_buf.data);
174  errcontext("COPY %s, line %llu: \"%s\"",
175  cstate->cur_relname,
176  (unsigned long long) cstate->cur_lineno, lineval);
177  pfree(lineval);
178  }
179  else
180  {
181  errcontext("COPY %s, line %llu",
182  cstate->cur_relname,
183  (unsigned long long) cstate->cur_lineno);
184  }
185  }
186  }
187 }
188 
189 /*
190  * Make sure we don't print an unreasonable amount of COPY data in a message.
191  *
192  * Returns a pstrdup'd copy of the input.
193  */
194 static char *
196 {
197 #define MAX_COPY_DATA_DISPLAY 100
198 
199  int slen = strlen(str);
200  int len;
201  char *res;
202 
203  /* Fast path if definitely okay */
204  if (slen <= MAX_COPY_DATA_DISPLAY)
205  return pstrdup(str);
206 
207  /* Apply encoding-dependent truncation */
209 
210  /*
211  * Truncate, and add "..." to show we truncated the input.
212  */
213  res = (char *) palloc(len + 4);
214  memcpy(res, str, len);
215  strcpy(res + len, "...");
216 
217  return res;
218 }
219 
220 /*
221  * Allocate memory and initialize a new CopyMultiInsertBuffer for this
222  * ResultRelInfo.
223  */
224 static CopyMultiInsertBuffer *
226 {
227  CopyMultiInsertBuffer *buffer;
228 
229  buffer = (CopyMultiInsertBuffer *) palloc(sizeof(CopyMultiInsertBuffer));
230  memset(buffer->slots, 0, sizeof(TupleTableSlot *) * MAX_BUFFERED_TUPLES);
231  buffer->resultRelInfo = rri;
232  buffer->bistate = (rri->ri_FdwRoutine == NULL) ? GetBulkInsertState() : NULL;
233  buffer->nused = 0;
234 
235  return buffer;
236 }
237 
238 /*
239  * Make a new buffer for this ResultRelInfo.
240  */
241 static inline void
243  ResultRelInfo *rri)
244 {
245  CopyMultiInsertBuffer *buffer;
246 
247  buffer = CopyMultiInsertBufferInit(rri);
248 
249  /* Setup back-link so we can easily find this buffer again */
250  rri->ri_CopyMultiInsertBuffer = buffer;
251  /* Record that we're tracking this buffer */
252  miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer);
253 }
254 
255 /*
256  * Initialize an already allocated CopyMultiInsertInfo.
257  *
258  * If rri is a non-partitioned table then a CopyMultiInsertBuffer is set up
259  * for that table.
260  */
261 static void
263  CopyFromState cstate, EState *estate, CommandId mycid,
264  int ti_options)
265 {
266  miinfo->multiInsertBuffers = NIL;
267  miinfo->bufferedTuples = 0;
268  miinfo->bufferedBytes = 0;
269  miinfo->cstate = cstate;
270  miinfo->estate = estate;
271  miinfo->mycid = mycid;
272  miinfo->ti_options = ti_options;
273 
274  /*
275  * Only setup the buffer when not dealing with a partitioned table.
276  * Buffers for partitioned tables will just be setup when we need to send
277  * tuples their way for the first time.
278  */
279  if (rri->ri_RelationDesc->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
280  CopyMultiInsertInfoSetupBuffer(miinfo, rri);
281 }
282 
283 /*
284  * Returns true if the buffers are full
285  */
286 static inline bool
288 {
289  if (miinfo->bufferedTuples >= MAX_BUFFERED_TUPLES ||
291  return true;
292  return false;
293 }
294 
295 /*
296  * Returns true if we have no buffered tuples
297  */
298 static inline bool
300 {
301  return miinfo->bufferedTuples == 0;
302 }
303 
304 /*
305  * Write the tuples stored in 'buffer' out to the table.
306  */
307 static inline void
309  CopyMultiInsertBuffer *buffer,
310  int64 *processed)
311 {
312  CopyFromState cstate = miinfo->cstate;
313  EState *estate = miinfo->estate;
314  int nused = buffer->nused;
315  ResultRelInfo *resultRelInfo = buffer->resultRelInfo;
316  TupleTableSlot **slots = buffer->slots;
317  int i;
318 
319  if (resultRelInfo->ri_FdwRoutine)
320  {
321  int batch_size = resultRelInfo->ri_BatchSize;
322  int sent = 0;
323 
324  Assert(buffer->bistate == NULL);
325 
326  /* Ensure that the FDW supports batching and it's enabled */
328  Assert(batch_size > 1);
329 
330  /*
331  * We suppress error context information other than the relation name,
332  * if one of the operations below fails.
333  */
334  Assert(!cstate->relname_only);
335  cstate->relname_only = true;
336 
337  while (sent < nused)
338  {
339  int size = (batch_size < nused - sent) ? batch_size : (nused - sent);
340  int inserted = size;
341  TupleTableSlot **rslots;
342 
343  /* insert into foreign table: let the FDW do it */
344  rslots =
345  resultRelInfo->ri_FdwRoutine->ExecForeignBatchInsert(estate,
346  resultRelInfo,
347  &slots[sent],
348  NULL,
349  &inserted);
350 
351  sent += size;
352 
353  /* No need to do anything if there are no inserted rows */
354  if (inserted <= 0)
355  continue;
356 
357  /* Triggers on foreign tables should not have transition tables */
358  Assert(resultRelInfo->ri_TrigDesc == NULL ||
359  resultRelInfo->ri_TrigDesc->trig_insert_new_table == false);
360 
361  /* Run AFTER ROW INSERT triggers */
362  if (resultRelInfo->ri_TrigDesc != NULL &&
363  resultRelInfo->ri_TrigDesc->trig_insert_after_row)
364  {
365  Oid relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
366 
367  for (i = 0; i < inserted; i++)
368  {
369  TupleTableSlot *slot = rslots[i];
370 
371  /*
372  * AFTER ROW Triggers might reference the tableoid column,
373  * so (re-)initialize tts_tableOid before evaluating them.
374  */
375  slot->tts_tableOid = relid;
376 
377  ExecARInsertTriggers(estate, resultRelInfo,
378  slot, NIL,
379  cstate->transition_capture);
380  }
381  }
382 
383  /* Update the row counter and progress of the COPY command */
384  *processed += inserted;
386  *processed);
387  }
388 
389  for (i = 0; i < nused; i++)
390  ExecClearTuple(slots[i]);
391 
392  /* reset relname_only */
393  cstate->relname_only = false;
394  }
395  else
396  {
397  CommandId mycid = miinfo->mycid;
398  int ti_options = miinfo->ti_options;
399  bool line_buf_valid = cstate->line_buf_valid;
400  uint64 save_cur_lineno = cstate->cur_lineno;
401  MemoryContext oldcontext;
402 
403  Assert(buffer->bistate != NULL);
404 
405  /*
406  * Print error context information correctly, if one of the operations
407  * below fails.
408  */
409  cstate->line_buf_valid = false;
410 
411  /*
412  * table_multi_insert may leak memory, so switch to short-lived memory
413  * context before calling it.
414  */
415  oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
416  table_multi_insert(resultRelInfo->ri_RelationDesc,
417  slots,
418  nused,
419  mycid,
420  ti_options,
421  buffer->bistate);
422  MemoryContextSwitchTo(oldcontext);
423 
424  for (i = 0; i < nused; i++)
425  {
426  /*
427  * If there are any indexes, update them for all the inserted
428  * tuples, and run AFTER ROW INSERT triggers.
429  */
430  if (resultRelInfo->ri_NumIndices > 0)
431  {
432  List *recheckIndexes;
433 
434  cstate->cur_lineno = buffer->linenos[i];
435  recheckIndexes =
436  ExecInsertIndexTuples(resultRelInfo,
437  buffer->slots[i], estate, false,
438  false, NULL, NIL);
439  ExecARInsertTriggers(estate, resultRelInfo,
440  slots[i], recheckIndexes,
441  cstate->transition_capture);
442  list_free(recheckIndexes);
443  }
444 
445  /*
446  * There's no indexes, but see if we need to run AFTER ROW INSERT
447  * triggers anyway.
448  */
449  else if (resultRelInfo->ri_TrigDesc != NULL &&
450  (resultRelInfo->ri_TrigDesc->trig_insert_after_row ||
451  resultRelInfo->ri_TrigDesc->trig_insert_new_table))
452  {
453  cstate->cur_lineno = buffer->linenos[i];
454  ExecARInsertTriggers(estate, resultRelInfo,
455  slots[i], NIL,
456  cstate->transition_capture);
457  }
458 
459  ExecClearTuple(slots[i]);
460  }
461 
462  /* Update the row counter and progress of the COPY command */
463  *processed += nused;
465  *processed);
466 
467  /* reset cur_lineno and line_buf_valid to what they were */
468  cstate->line_buf_valid = line_buf_valid;
469  cstate->cur_lineno = save_cur_lineno;
470  }
471 
472  /* Mark that all slots are free */
473  buffer->nused = 0;
474 }
475 
476 /*
477  * Drop used slots and free member for this buffer.
478  *
479  * The buffer must be flushed before cleanup.
480  */
481 static inline void
483  CopyMultiInsertBuffer *buffer)
484 {
485  ResultRelInfo *resultRelInfo = buffer->resultRelInfo;
486  int i;
487 
488  /* Ensure buffer was flushed */
489  Assert(buffer->nused == 0);
490 
491  /* Remove back-link to ourself */
492  resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
493 
494  if (resultRelInfo->ri_FdwRoutine == NULL)
495  {
496  Assert(buffer->bistate != NULL);
497  FreeBulkInsertState(buffer->bistate);
498  }
499  else
500  Assert(buffer->bistate == NULL);
501 
502  /* Since we only create slots on demand, just drop the non-null ones. */
503  for (i = 0; i < MAX_BUFFERED_TUPLES && buffer->slots[i] != NULL; i++)
505 
506  if (resultRelInfo->ri_FdwRoutine == NULL)
508  miinfo->ti_options);
509 
510  pfree(buffer);
511 }
512 
513 /*
514  * Write out all stored tuples in all buffers out to the tables.
515  *
516  * Once flushed we also trim the tracked buffers list down to size by removing
517  * the buffers created earliest first.
518  *
519  * Callers should pass 'curr_rri' as the ResultRelInfo that's currently being
520  * used. When cleaning up old buffers we'll never remove the one for
521  * 'curr_rri'.
522  */
523 static inline void
525  int64 *processed)
526 {
527  ListCell *lc;
528 
529  foreach(lc, miinfo->multiInsertBuffers)
530  {
532 
533  CopyMultiInsertBufferFlush(miinfo, buffer, processed);
534  }
535 
536  miinfo->bufferedTuples = 0;
537  miinfo->bufferedBytes = 0;
538 
539  /*
540  * Trim the list of tracked buffers down if it exceeds the limit. Here we
541  * remove buffers starting with the ones we created first. It seems less
542  * likely that these older ones will be needed than the ones that were
543  * just created.
544  */
546  {
547  CopyMultiInsertBuffer *buffer;
548 
549  buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers);
550 
551  /*
552  * We never want to remove the buffer that's currently being used, so
553  * if we happen to find that then move it to the end of the list.
554  */
555  if (buffer->resultRelInfo == curr_rri)
556  {
558  miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer);
559  buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers);
560  }
561 
562  CopyMultiInsertBufferCleanup(miinfo, buffer);
564  }
565 }
566 
567 /*
568  * Cleanup allocated buffers and free memory
569  */
570 static inline void
572 {
573  ListCell *lc;
574 
575  foreach(lc, miinfo->multiInsertBuffers)
577 
578  list_free(miinfo->multiInsertBuffers);
579 }
580 
581 /*
582  * Get the next TupleTableSlot that the next tuple should be stored in.
583  *
584  * Callers must ensure that the buffer is not full.
585  *
586  * Note: 'miinfo' is unused but has been included for consistency with the
587  * other functions in this area.
588  */
589 static inline TupleTableSlot *
591  ResultRelInfo *rri)
592 {
594  int nused = buffer->nused;
595 
596  Assert(buffer != NULL);
597  Assert(nused < MAX_BUFFERED_TUPLES);
598 
599  if (buffer->slots[nused] == NULL)
600  buffer->slots[nused] = table_slot_create(rri->ri_RelationDesc, NULL);
601  return buffer->slots[nused];
602 }
603 
604 /*
605  * Record the previously reserved TupleTableSlot that was reserved by
606  * CopyMultiInsertInfoNextFreeSlot as being consumed.
607  */
608 static inline void
610  TupleTableSlot *slot, int tuplen, uint64 lineno)
611 {
613 
614  Assert(buffer != NULL);
615  Assert(slot == buffer->slots[buffer->nused]);
616 
617  /* Store the line number so we can properly report any errors later */
618  buffer->linenos[buffer->nused] = lineno;
619 
620  /* Record this slot as being used */
621  buffer->nused++;
622 
623  /* Update how many tuples are stored and their size */
624  miinfo->bufferedTuples++;
625  miinfo->bufferedBytes += tuplen;
626 }
627 
628 /*
629  * Copy FROM file to relation.
630  */
631 uint64
633 {
634  ResultRelInfo *resultRelInfo;
635  ResultRelInfo *target_resultRelInfo;
636  ResultRelInfo *prevResultRelInfo = NULL;
637  EState *estate = CreateExecutorState(); /* for ExecConstraints() */
638  ModifyTableState *mtstate;
639  ExprContext *econtext;
640  TupleTableSlot *singleslot = NULL;
641  MemoryContext oldcontext = CurrentMemoryContext;
642 
643  PartitionTupleRouting *proute = NULL;
644  ErrorContextCallback errcallback;
645  CommandId mycid = GetCurrentCommandId(true);
646  int ti_options = 0; /* start with default options for insert */
647  BulkInsertState bistate = NULL;
648  CopyInsertMethod insertMethod;
649  CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
650  int64 processed = 0;
651  int64 excluded = 0;
652  bool has_before_insert_row_trig;
653  bool has_instead_insert_row_trig;
654  bool leafpart_use_multi_insert = false;
655 
656  Assert(cstate->rel);
657  Assert(list_length(cstate->range_table) == 1);
658 
659  /*
660  * The target must be a plain, foreign, or partitioned relation, or have
661  * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
662  * allowed on views, so we only hint about them in the view case.)
663  */
664  if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
665  cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
666  cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
667  !(cstate->rel->trigdesc &&
669  {
670  if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
671  ereport(ERROR,
672  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
673  errmsg("cannot copy to view \"%s\"",
674  RelationGetRelationName(cstate->rel)),
675  errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
676  else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
677  ereport(ERROR,
678  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
679  errmsg("cannot copy to materialized view \"%s\"",
680  RelationGetRelationName(cstate->rel))));
681  else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
682  ereport(ERROR,
683  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
684  errmsg("cannot copy to sequence \"%s\"",
685  RelationGetRelationName(cstate->rel))));
686  else
687  ereport(ERROR,
688  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
689  errmsg("cannot copy to non-table relation \"%s\"",
690  RelationGetRelationName(cstate->rel))));
691  }
692 
693  /*
694  * If the target file is new-in-transaction, we assume that checking FSM
695  * for free space is a waste of time. This could possibly be wrong, but
696  * it's unlikely.
697  */
698  if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) &&
701  ti_options |= TABLE_INSERT_SKIP_FSM;
702 
703  /*
704  * Optimize if new relation storage was created in this subxact or one of
705  * its committed children and we won't see those rows later as part of an
706  * earlier scan or command. The subxact test ensures that if this subxact
707  * aborts then the frozen rows won't be visible after xact cleanup. Note
708  * that the stronger test of exactly which subtransaction created it is
709  * crucial for correctness of this optimization. The test for an earlier
710  * scan or command tolerates false negatives. FREEZE causes other sessions
711  * to see rows they would not see under MVCC, and a false negative merely
712  * spreads that anomaly to the current session.
713  */
714  if (cstate->opts.freeze)
715  {
716  /*
717  * We currently disallow COPY FREEZE on partitioned tables. The
718  * reason for this is that we've simply not yet opened the partitions
719  * to determine if the optimization can be applied to them. We could
720  * go and open them all here, but doing so may be quite a costly
721  * overhead for small copies. In any case, we may just end up routing
722  * tuples to a small number of partitions. It seems better just to
723  * raise an ERROR for partitioned tables.
724  */
725  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
726  {
727  ereport(ERROR,
728  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
729  errmsg("cannot perform COPY FREEZE on a partitioned table")));
730  }
731 
732  /*
733  * Tolerate one registration for the benefit of FirstXactSnapshot.
734  * Scan-bearing queries generally create at least two registrations,
735  * though relying on that is fragile, as is ignoring ActiveSnapshot.
736  * Clear CatalogSnapshot to avoid counting its registration. We'll
737  * still detect ongoing catalog scans, each of which separately
738  * registers the snapshot it uses.
739  */
742  ereport(ERROR,
743  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
744  errmsg("cannot perform COPY FREEZE because of prior transaction activity")));
745 
746  if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() &&
748  ereport(ERROR,
749  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
750  errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction")));
751 
752  ti_options |= TABLE_INSERT_FROZEN;
753  }
754 
755  /*
756  * We need a ResultRelInfo so we can use the regular executor's
757  * index-entry-making machinery. (There used to be a huge amount of code
758  * here that basically duplicated execUtils.c ...)
759  */
760  ExecInitRangeTable(estate, cstate->range_table);
761  resultRelInfo = target_resultRelInfo = makeNode(ResultRelInfo);
762  ExecInitResultRelation(estate, resultRelInfo, 1);
763 
764  /*
765  * Copy the RTEPermissionInfos into estate as well, so that
766  * ExecGetInsertedCols() et al will work correctly.
767  */
768  estate->es_rteperminfos = cstate->rteperminfos;
769 
770  /* Verify the named relation is a valid target for INSERT */
771  CheckValidResultRel(resultRelInfo, CMD_INSERT);
772 
773  ExecOpenIndices(resultRelInfo, false);
774 
775  /*
776  * Set up a ModifyTableState so we can let FDW(s) init themselves for
777  * foreign-table result relation(s).
778  */
779  mtstate = makeNode(ModifyTableState);
780  mtstate->ps.plan = NULL;
781  mtstate->ps.state = estate;
782  mtstate->operation = CMD_INSERT;
783  mtstate->mt_nrels = 1;
784  mtstate->resultRelInfo = resultRelInfo;
785  mtstate->rootResultRelInfo = resultRelInfo;
786 
787  if (resultRelInfo->ri_FdwRoutine != NULL &&
788  resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
789  resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate,
790  resultRelInfo);
791 
792  /*
793  * Also, if the named relation is a foreign table, determine if the FDW
794  * supports batch insert and determine the batch size (a FDW may support
795  * batching, but it may be disabled for the server/table).
796  *
797  * If the FDW does not support batching, we set the batch size to 1.
798  */
799  if (resultRelInfo->ri_FdwRoutine != NULL &&
800  resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize &&
801  resultRelInfo->ri_FdwRoutine->ExecForeignBatchInsert)
802  resultRelInfo->ri_BatchSize =
803  resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(resultRelInfo);
804  else
805  resultRelInfo->ri_BatchSize = 1;
806 
807  Assert(resultRelInfo->ri_BatchSize >= 1);
808 
809  /* Prepare to catch AFTER triggers. */
811 
812  /*
813  * If there are any triggers with transition tables on the named relation,
814  * we need to be prepared to capture transition tuples.
815  *
816  * Because partition tuple routing would like to know about whether
817  * transition capture is active, we also set it in mtstate, which is
818  * passed to ExecFindPartition() below.
819  */
820  cstate->transition_capture = mtstate->mt_transition_capture =
822  RelationGetRelid(cstate->rel),
823  CMD_INSERT);
824 
825  /*
826  * If the named relation is a partitioned table, initialize state for
827  * CopyFrom tuple routing.
828  */
829  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
830  proute = ExecSetupPartitionTupleRouting(estate, cstate->rel);
831 
832  if (cstate->whereClause)
833  cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
834  &mtstate->ps);
835 
836  /*
837  * It's generally more efficient to prepare a bunch of tuples for
838  * insertion, and insert them in one
839  * table_multi_insert()/ExecForeignBatchInsert() call, than call
840  * table_tuple_insert()/ExecForeignInsert() separately for every tuple.
841  * However, there are a number of reasons why we might not be able to do
842  * this. These are explained below.
843  */
844  if (resultRelInfo->ri_TrigDesc != NULL &&
845  (resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
846  resultRelInfo->ri_TrigDesc->trig_insert_instead_row))
847  {
848  /*
849  * Can't support multi-inserts when there are any BEFORE/INSTEAD OF
850  * triggers on the table. Such triggers might query the table we're
851  * inserting into and act differently if the tuples that have already
852  * been processed and prepared for insertion are not there.
853  */
854  insertMethod = CIM_SINGLE;
855  }
856  else if (resultRelInfo->ri_FdwRoutine != NULL &&
857  resultRelInfo->ri_BatchSize == 1)
858  {
859  /*
860  * Can't support multi-inserts to a foreign table if the FDW does not
861  * support batching, or it's disabled for the server or foreign table.
862  */
863  insertMethod = CIM_SINGLE;
864  }
865  else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL &&
866  resultRelInfo->ri_TrigDesc->trig_insert_new_table)
867  {
868  /*
869  * For partitioned tables we can't support multi-inserts when there
870  * are any statement level insert triggers. It might be possible to
871  * allow partitioned tables with such triggers in the future, but for
872  * now, CopyMultiInsertInfoFlush expects that any after row insert and
873  * statement level insert triggers are on the same relation.
874  */
875  insertMethod = CIM_SINGLE;
876  }
877  else if (cstate->volatile_defexprs)
878  {
879  /*
880  * Can't support multi-inserts if there are any volatile default
881  * expressions in the table. Similarly to the trigger case above,
882  * such expressions may query the table we're inserting into.
883  *
884  * Note: It does not matter if any partitions have any volatile
885  * default expressions as we use the defaults from the target of the
886  * COPY command.
887  */
888  insertMethod = CIM_SINGLE;
889  }
890  else if (contain_volatile_functions(cstate->whereClause))
891  {
892  /*
893  * Can't support multi-inserts if there are any volatile function
894  * expressions in WHERE clause. Similarly to the trigger case above,
895  * such expressions may query the table we're inserting into.
896  */
897  insertMethod = CIM_SINGLE;
898  }
899  else
900  {
901  /*
902  * For partitioned tables, we may still be able to perform bulk
903  * inserts. However, the possibility of this depends on which types
904  * of triggers exist on the partition. We must disable bulk inserts
905  * if the partition is a foreign table that can't use batching or it
906  * has any before row insert or insert instead triggers (same as we
907  * checked above for the parent table). Since the partition's
908  * resultRelInfos are initialized only when we actually need to insert
909  * the first tuple into them, we must have the intermediate insert
910  * method of CIM_MULTI_CONDITIONAL to flag that we must later
911  * determine if we can use bulk-inserts for the partition being
912  * inserted into.
913  */
914  if (proute)
915  insertMethod = CIM_MULTI_CONDITIONAL;
916  else
917  insertMethod = CIM_MULTI;
918 
919  CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate,
920  estate, mycid, ti_options);
921  }
922 
923  /*
924  * If not using batch mode (which allocates slots as needed) set up a
925  * tuple slot too. When inserting into a partitioned table, we also need
926  * one, even if we might batch insert, to read the tuple in the root
927  * partition's form.
928  */
929  if (insertMethod == CIM_SINGLE || insertMethod == CIM_MULTI_CONDITIONAL)
930  {
931  singleslot = table_slot_create(resultRelInfo->ri_RelationDesc,
932  &estate->es_tupleTable);
933  bistate = GetBulkInsertState();
934  }
935 
936  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
937  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
938 
939  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
940  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
941 
942  /*
943  * Check BEFORE STATEMENT insertion triggers. It's debatable whether we
944  * should do this for COPY, since it's not really an "INSERT" statement as
945  * such. However, executing these triggers maintains consistency with the
946  * EACH ROW triggers that we already fire on COPY.
947  */
948  ExecBSInsertTriggers(estate, resultRelInfo);
949 
950  econtext = GetPerTupleExprContext(estate);
951 
952  /* Set up callback to identify error line number */
953  errcallback.callback = CopyFromErrorCallback;
954  errcallback.arg = (void *) cstate;
955  errcallback.previous = error_context_stack;
956  error_context_stack = &errcallback;
957 
958  for (;;)
959  {
960  TupleTableSlot *myslot;
961  bool skip_tuple;
962 
964 
965  /*
966  * Reset the per-tuple exprcontext. We do this after every tuple, to
967  * clean-up after expression evaluations etc.
968  */
969  ResetPerTupleExprContext(estate);
970 
971  /* select slot to (initially) load row into */
972  if (insertMethod == CIM_SINGLE || proute)
973  {
974  myslot = singleslot;
975  Assert(myslot != NULL);
976  }
977  else
978  {
979  Assert(resultRelInfo == target_resultRelInfo);
980  Assert(insertMethod == CIM_MULTI);
981 
982  myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
983  resultRelInfo);
984  }
985 
986  /*
987  * Switch to per-tuple context before calling NextCopyFrom, which does
988  * evaluate default expressions etc. and requires per-tuple context.
989  */
991 
992  ExecClearTuple(myslot);
993 
994  /* Directly store the values/nulls array in the slot */
995  if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
996  break;
997 
998  ExecStoreVirtualTuple(myslot);
999 
1000  /*
1001  * Constraints and where clause might reference the tableoid column,
1002  * so (re-)initialize tts_tableOid before evaluating them.
1003  */
1004  myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
1005 
1006  /* Triggers and stuff need to be invoked in query context. */
1007  MemoryContextSwitchTo(oldcontext);
1008 
1009  if (cstate->whereClause)
1010  {
1011  econtext->ecxt_scantuple = myslot;
1012  /* Skip items that don't match COPY's WHERE clause */
1013  if (!ExecQual(cstate->qualexpr, econtext))
1014  {
1015  /*
1016  * Report that this tuple was filtered out by the WHERE
1017  * clause.
1018  */
1020  ++excluded);
1021  continue;
1022  }
1023  }
1024 
1025  /* Determine the partition to insert the tuple into */
1026  if (proute)
1027  {
1028  TupleConversionMap *map;
1029 
1030  /*
1031  * Attempt to find a partition suitable for this tuple.
1032  * ExecFindPartition() will raise an error if none can be found or
1033  * if the found partition is not suitable for INSERTs.
1034  */
1035  resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
1036  proute, myslot, estate);
1037 
1038  if (prevResultRelInfo != resultRelInfo)
1039  {
1040  /* Determine which triggers exist on this partition */
1041  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1042  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
1043 
1044  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
1045  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
1046 
1047  /*
1048  * Disable multi-inserts when the partition has BEFORE/INSTEAD
1049  * OF triggers, or if the partition is a foreign table that
1050  * can't use batching.
1051  */
1052  leafpart_use_multi_insert = insertMethod == CIM_MULTI_CONDITIONAL &&
1053  !has_before_insert_row_trig &&
1054  !has_instead_insert_row_trig &&
1055  (resultRelInfo->ri_FdwRoutine == NULL ||
1056  resultRelInfo->ri_BatchSize > 1);
1057 
1058  /* Set the multi-insert buffer to use for this partition. */
1059  if (leafpart_use_multi_insert)
1060  {
1061  if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL)
1062  CopyMultiInsertInfoSetupBuffer(&multiInsertInfo,
1063  resultRelInfo);
1064  }
1065  else if (insertMethod == CIM_MULTI_CONDITIONAL &&
1066  !CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
1067  {
1068  /*
1069  * Flush pending inserts if this partition can't use
1070  * batching, so rows are visible to triggers etc.
1071  */
1072  CopyMultiInsertInfoFlush(&multiInsertInfo,
1073  resultRelInfo,
1074  &processed);
1075  }
1076 
1077  if (bistate != NULL)
1078  ReleaseBulkInsertStatePin(bistate);
1079  prevResultRelInfo = resultRelInfo;
1080  }
1081 
1082  /*
1083  * If we're capturing transition tuples, we might need to convert
1084  * from the partition rowtype to root rowtype. But if there are no
1085  * BEFORE triggers on the partition that could change the tuple,
1086  * we can just remember the original unconverted tuple to avoid a
1087  * needless round trip conversion.
1088  */
1089  if (cstate->transition_capture != NULL)
1091  !has_before_insert_row_trig ? myslot : NULL;
1092 
1093  /*
1094  * We might need to convert from the root rowtype to the partition
1095  * rowtype.
1096  */
1097  map = ExecGetRootToChildMap(resultRelInfo, estate);
1098  if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert)
1099  {
1100  /* non batch insert */
1101  if (map != NULL)
1102  {
1103  TupleTableSlot *new_slot;
1104 
1105  new_slot = resultRelInfo->ri_PartitionTupleSlot;
1106  myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
1107  }
1108  }
1109  else
1110  {
1111  /*
1112  * Prepare to queue up tuple for later batch insert into
1113  * current partition.
1114  */
1115  TupleTableSlot *batchslot;
1116 
1117  /* no other path available for partitioned table */
1118  Assert(insertMethod == CIM_MULTI_CONDITIONAL);
1119 
1120  batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
1121  resultRelInfo);
1122 
1123  if (map != NULL)
1124  myslot = execute_attr_map_slot(map->attrMap, myslot,
1125  batchslot);
1126  else
1127  {
1128  /*
1129  * This looks more expensive than it is (Believe me, I
1130  * optimized it away. Twice.). The input is in virtual
1131  * form, and we'll materialize the slot below - for most
1132  * slot types the copy performs the work materialization
1133  * would later require anyway.
1134  */
1135  ExecCopySlot(batchslot, myslot);
1136  myslot = batchslot;
1137  }
1138  }
1139 
1140  /* ensure that triggers etc see the right relation */
1141  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1142  }
1143 
1144  skip_tuple = false;
1145 
1146  /* BEFORE ROW INSERT Triggers */
1147  if (has_before_insert_row_trig)
1148  {
1149  if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot))
1150  skip_tuple = true; /* "do nothing" */
1151  }
1152 
1153  if (!skip_tuple)
1154  {
1155  /*
1156  * If there is an INSTEAD OF INSERT ROW trigger, let it handle the
1157  * tuple. Otherwise, proceed with inserting the tuple into the
1158  * table or foreign table.
1159  */
1160  if (has_instead_insert_row_trig)
1161  {
1162  ExecIRInsertTriggers(estate, resultRelInfo, myslot);
1163  }
1164  else
1165  {
1166  /* Compute stored generated columns */
1167  if (resultRelInfo->ri_RelationDesc->rd_att->constr &&
1169  ExecComputeStoredGenerated(resultRelInfo, estate, myslot,
1170  CMD_INSERT);
1171 
1172  /*
1173  * If the target is a plain table, check the constraints of
1174  * the tuple.
1175  */
1176  if (resultRelInfo->ri_FdwRoutine == NULL &&
1177  resultRelInfo->ri_RelationDesc->rd_att->constr)
1178  ExecConstraints(resultRelInfo, myslot, estate);
1179 
1180  /*
1181  * Also check the tuple against the partition constraint, if
1182  * there is one; except that if we got here via tuple-routing,
1183  * we don't need to if there's no BR trigger defined on the
1184  * partition.
1185  */
1186  if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition &&
1187  (proute == NULL || has_before_insert_row_trig))
1188  ExecPartitionCheck(resultRelInfo, myslot, estate, true);
1189 
1190  /* Store the slot in the multi-insert buffer, when enabled. */
1191  if (insertMethod == CIM_MULTI || leafpart_use_multi_insert)
1192  {
1193  /*
1194  * The slot previously might point into the per-tuple
1195  * context. For batching it needs to be longer lived.
1196  */
1197  ExecMaterializeSlot(myslot);
1198 
1199  /* Add this tuple to the tuple buffer */
1200  CopyMultiInsertInfoStore(&multiInsertInfo,
1201  resultRelInfo, myslot,
1202  cstate->line_buf.len,
1203  cstate->cur_lineno);
1204 
1205  /*
1206  * If enough inserts have queued up, then flush all
1207  * buffers out to their tables.
1208  */
1209  if (CopyMultiInsertInfoIsFull(&multiInsertInfo))
1210  CopyMultiInsertInfoFlush(&multiInsertInfo,
1211  resultRelInfo,
1212  &processed);
1213 
1214  /*
1215  * We delay updating the row counter and progress of the
1216  * COPY command until after writing the tuples stored in
1217  * the buffer out to the table, as in single insert mode.
1218  * See CopyMultiInsertBufferFlush().
1219  */
1220  continue; /* next tuple please */
1221  }
1222  else
1223  {
1224  List *recheckIndexes = NIL;
1225 
1226  /* OK, store the tuple */
1227  if (resultRelInfo->ri_FdwRoutine != NULL)
1228  {
1229  myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
1230  resultRelInfo,
1231  myslot,
1232  NULL);
1233 
1234  if (myslot == NULL) /* "do nothing" */
1235  continue; /* next tuple please */
1236 
1237  /*
1238  * AFTER ROW Triggers might reference the tableoid
1239  * column, so (re-)initialize tts_tableOid before
1240  * evaluating them.
1241  */
1242  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1243  }
1244  else
1245  {
1246  /* OK, store the tuple and create index entries for it */
1247  table_tuple_insert(resultRelInfo->ri_RelationDesc,
1248  myslot, mycid, ti_options, bistate);
1249 
1250  if (resultRelInfo->ri_NumIndices > 0)
1251  recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
1252  myslot,
1253  estate,
1254  false,
1255  false,
1256  NULL,
1257  NIL);
1258  }
1259 
1260  /* AFTER ROW INSERT Triggers */
1261  ExecARInsertTriggers(estate, resultRelInfo, myslot,
1262  recheckIndexes, cstate->transition_capture);
1263 
1264  list_free(recheckIndexes);
1265  }
1266  }
1267 
1268  /*
1269  * We count only tuples not suppressed by a BEFORE INSERT trigger
1270  * or FDW; this is the same definition used by nodeModifyTable.c
1271  * for counting tuples inserted by an INSERT command. Update
1272  * progress of the COPY command as well.
1273  */
1275  ++processed);
1276  }
1277  }
1278 
1279  /* Flush any remaining buffered tuples */
1280  if (insertMethod != CIM_SINGLE)
1281  {
1282  if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
1283  CopyMultiInsertInfoFlush(&multiInsertInfo, NULL, &processed);
1284  }
1285 
1286  /* Done, clean up */
1287  error_context_stack = errcallback.previous;
1288 
1289  if (bistate != NULL)
1290  FreeBulkInsertState(bistate);
1291 
1292  MemoryContextSwitchTo(oldcontext);
1293 
1294  /* Execute AFTER STATEMENT insertion triggers */
1295  ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture);
1296 
1297  /* Handle queued AFTER triggers */
1298  AfterTriggerEndQuery(estate);
1299 
1300  ExecResetTupleTable(estate->es_tupleTable, false);
1301 
1302  /* Allow the FDW to shut down */
1303  if (target_resultRelInfo->ri_FdwRoutine != NULL &&
1304  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
1305  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate,
1306  target_resultRelInfo);
1307 
1308  /* Tear down the multi-insert buffer data */
1309  if (insertMethod != CIM_SINGLE)
1310  CopyMultiInsertInfoCleanup(&multiInsertInfo);
1311 
1312  /* Close all the partitioned tables, leaf partitions, and their indices */
1313  if (proute)
1314  ExecCleanupTupleRouting(mtstate, proute);
1315 
1316  /* Close the result relations, including any trigger target relations */
1317  ExecCloseResultRelations(estate);
1319 
1320  FreeExecutorState(estate);
1321 
1322  return processed;
1323 }
1324 
1325 /*
1326  * Setup to read tuples from a file for COPY FROM.
1327  *
1328  * 'rel': Used as a template for the tuples
1329  * 'whereClause': WHERE clause from the COPY FROM command
1330  * 'filename': Name of server-local file to read, NULL for STDIN
1331  * 'is_program': true if 'filename' is program to execute
1332  * 'data_source_cb': callback that provides the input data
1333  * 'attnamelist': List of char *, columns to include. NIL selects all cols.
1334  * 'options': List of DefElem. See copy_opt_item in gram.y for selections.
1335  *
1336  * Returns a CopyFromState, to be passed to NextCopyFrom and related functions.
1337  */
1340  Relation rel,
1341  Node *whereClause,
1342  const char *filename,
1343  bool is_program,
1344  copy_data_source_cb data_source_cb,
1345  List *attnamelist,
1346  List *options)
1347 {
1348  CopyFromState cstate;
1349  bool pipe = (filename == NULL);
1350  TupleDesc tupDesc;
1351  AttrNumber num_phys_attrs,
1352  num_defaults;
1353  FmgrInfo *in_functions;
1354  Oid *typioparams;
1355  Oid in_func_oid;
1356  int *defmap;
1357  ExprState **defexprs;
1358  MemoryContext oldcontext;
1359  bool volatile_defexprs;
1360  const int progress_cols[] = {
1364  };
1365  int64 progress_vals[] = {
1367  0,
1368  0
1369  };
1370 
1371  /* Allocate workspace and zero all fields */
1372  cstate = (CopyFromStateData *) palloc0(sizeof(CopyFromStateData));
1373 
1374  /*
1375  * We allocate everything used by a cstate in a new memory context. This
1376  * avoids memory leaks during repeated use of COPY in a query.
1377  */
1379  "COPY",
1381 
1382  oldcontext = MemoryContextSwitchTo(cstate->copycontext);
1383 
1384  /* Extract options from the statement node tree */
1385  ProcessCopyOptions(pstate, &cstate->opts, true /* is_from */ , options);
1386 
1387  /* Process the target relation */
1388  cstate->rel = rel;
1389 
1390  tupDesc = RelationGetDescr(cstate->rel);
1391 
1392  /* process common options or initialization */
1393 
1394  /* Generate or convert list of attributes to process */
1395  cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
1396 
1397  num_phys_attrs = tupDesc->natts;
1398 
1399  /* Convert FORCE_NOT_NULL name list to per-column flags, check validity */
1400  cstate->opts.force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1401  if (cstate->opts.force_notnull)
1402  {
1403  List *attnums;
1404  ListCell *cur;
1405 
1406  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_notnull);
1407 
1408  foreach(cur, attnums)
1409  {
1410  int attnum = lfirst_int(cur);
1411  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1412 
1413  if (!list_member_int(cstate->attnumlist, attnum))
1414  ereport(ERROR,
1415  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1416  errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY",
1417  NameStr(attr->attname))));
1418  cstate->opts.force_notnull_flags[attnum - 1] = true;
1419  }
1420  }
1421 
1422  /* Convert FORCE_NULL name list to per-column flags, check validity */
1423  cstate->opts.force_null_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1424  if (cstate->opts.force_null)
1425  {
1426  List *attnums;
1427  ListCell *cur;
1428 
1429  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_null);
1430 
1431  foreach(cur, attnums)
1432  {
1433  int attnum = lfirst_int(cur);
1434  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1435 
1436  if (!list_member_int(cstate->attnumlist, attnum))
1437  ereport(ERROR,
1438  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1439  errmsg("FORCE_NULL column \"%s\" not referenced by COPY",
1440  NameStr(attr->attname))));
1441  cstate->opts.force_null_flags[attnum - 1] = true;
1442  }
1443  }
1444 
1445  /* Convert convert_selectively name list to per-column flags */
1446  if (cstate->opts.convert_selectively)
1447  {
1448  List *attnums;
1449  ListCell *cur;
1450 
1451  cstate->convert_select_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
1452 
1453  attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.convert_select);
1454 
1455  foreach(cur, attnums)
1456  {
1457  int attnum = lfirst_int(cur);
1458  Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
1459 
1460  if (!list_member_int(cstate->attnumlist, attnum))
1461  ereport(ERROR,
1462  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1463  errmsg_internal("selected column \"%s\" not referenced by COPY",
1464  NameStr(attr->attname))));
1465  cstate->convert_select_flags[attnum - 1] = true;
1466  }
1467  }
1468 
1469  /* Use client encoding when ENCODING option is not specified. */
1470  if (cstate->opts.file_encoding < 0)
1472  else
1473  cstate->file_encoding = cstate->opts.file_encoding;
1474 
1475  /*
1476  * Look up encoding conversion function.
1477  */
1478  if (cstate->file_encoding == GetDatabaseEncoding() ||
1479  cstate->file_encoding == PG_SQL_ASCII ||
1481  {
1482  cstate->need_transcoding = false;
1483  }
1484  else
1485  {
1486  cstate->need_transcoding = true;
1489  }
1490 
1491  cstate->copy_src = COPY_FILE; /* default */
1492 
1493  cstate->whereClause = whereClause;
1494 
1495  /* Initialize state variables */
1496  cstate->eol_type = EOL_UNKNOWN;
1497  cstate->cur_relname = RelationGetRelationName(cstate->rel);
1498  cstate->cur_lineno = 0;
1499  cstate->cur_attname = NULL;
1500  cstate->cur_attval = NULL;
1501  cstate->relname_only = false;
1502 
1503  /*
1504  * Allocate buffers for the input pipeline.
1505  *
1506  * attribute_buf and raw_buf are used in both text and binary modes, but
1507  * input_buf and line_buf only in text mode.
1508  */
1509  cstate->raw_buf = palloc(RAW_BUF_SIZE + 1);
1510  cstate->raw_buf_index = cstate->raw_buf_len = 0;
1511  cstate->raw_reached_eof = false;
1512 
1513  if (!cstate->opts.binary)
1514  {
1515  /*
1516  * If encoding conversion is needed, we need another buffer to hold
1517  * the converted input data. Otherwise, we can just point input_buf
1518  * to the same buffer as raw_buf.
1519  */
1520  if (cstate->need_transcoding)
1521  {
1522  cstate->input_buf = (char *) palloc(INPUT_BUF_SIZE + 1);
1523  cstate->input_buf_index = cstate->input_buf_len = 0;
1524  }
1525  else
1526  cstate->input_buf = cstate->raw_buf;
1527  cstate->input_reached_eof = false;
1528 
1529  initStringInfo(&cstate->line_buf);
1530  }
1531 
1532  initStringInfo(&cstate->attribute_buf);
1533 
1534  /* Assign range table and rteperminfos, we'll need them in CopyFrom. */
1535  if (pstate)
1536  {
1537  cstate->range_table = pstate->p_rtable;
1538  cstate->rteperminfos = pstate->p_rteperminfos;
1539  }
1540 
1541  tupDesc = RelationGetDescr(cstate->rel);
1542  num_phys_attrs = tupDesc->natts;
1543  num_defaults = 0;
1544  volatile_defexprs = false;
1545 
1546  /*
1547  * Pick up the required catalog information for each attribute in the
1548  * relation, including the input function, the element type (to pass to
1549  * the input function), and info about defaults and constraints. (Which
1550  * input function we use depends on text/binary format choice.)
1551  */
1552  in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
1553  typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
1554  defmap = (int *) palloc(num_phys_attrs * sizeof(int));
1555  defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
1556 
1557  for (int attnum = 1; attnum <= num_phys_attrs; attnum++)
1558  {
1559  Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
1560 
1561  /* We don't need info for dropped attributes */
1562  if (att->attisdropped)
1563  continue;
1564 
1565  /* Fetch the input function and typioparam info */
1566  if (cstate->opts.binary)
1567  getTypeBinaryInputInfo(att->atttypid,
1568  &in_func_oid, &typioparams[attnum - 1]);
1569  else
1570  getTypeInputInfo(att->atttypid,
1571  &in_func_oid, &typioparams[attnum - 1]);
1572  fmgr_info(in_func_oid, &in_functions[attnum - 1]);
1573 
1574  /* Get default info if needed */
1575  if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated)
1576  {
1577  /* attribute is NOT to be copied from input */
1578  /* use default value if one exists */
1579  Expr *defexpr = (Expr *) build_column_default(cstate->rel,
1580  attnum);
1581 
1582  if (defexpr != NULL)
1583  {
1584  /* Run the expression through planner */
1585  defexpr = expression_planner(defexpr);
1586 
1587  /* Initialize executable expression in copycontext */
1588  defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
1589  defmap[num_defaults] = attnum - 1;
1590  num_defaults++;
1591 
1592  /*
1593  * If a default expression looks at the table being loaded,
1594  * then it could give the wrong answer when using
1595  * multi-insert. Since database access can be dynamic this is
1596  * hard to test for exactly, so we use the much wider test of
1597  * whether the default expression is volatile. We allow for
1598  * the special case of when the default expression is the
1599  * nextval() of a sequence which in this specific case is
1600  * known to be safe for use with the multi-insert
1601  * optimization. Hence we use this special case function
1602  * checker rather than the standard check for
1603  * contain_volatile_functions().
1604  */
1605  if (!volatile_defexprs)
1606  volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr);
1607  }
1608  }
1609  }
1610 
1611 
1612  /* initialize progress */
1614  cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid);
1615  cstate->bytes_processed = 0;
1616 
1617  /* We keep those variables in cstate. */
1618  cstate->in_functions = in_functions;
1619  cstate->typioparams = typioparams;
1620  cstate->defmap = defmap;
1621  cstate->defexprs = defexprs;
1622  cstate->volatile_defexprs = volatile_defexprs;
1623  cstate->num_defaults = num_defaults;
1624  cstate->is_program = is_program;
1625 
1626  if (data_source_cb)
1627  {
1628  progress_vals[1] = PROGRESS_COPY_TYPE_CALLBACK;
1629  cstate->copy_src = COPY_CALLBACK;
1630  cstate->data_source_cb = data_source_cb;
1631  }
1632  else if (pipe)
1633  {
1634  progress_vals[1] = PROGRESS_COPY_TYPE_PIPE;
1635  Assert(!is_program); /* the grammar does not allow this */
1637  ReceiveCopyBegin(cstate);
1638  else
1639  cstate->copy_file = stdin;
1640  }
1641  else
1642  {
1643  cstate->filename = pstrdup(filename);
1644 
1645  if (cstate->is_program)
1646  {
1647  progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM;
1648  cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R);
1649  if (cstate->copy_file == NULL)
1650  ereport(ERROR,
1652  errmsg("could not execute command \"%s\": %m",
1653  cstate->filename)));
1654  }
1655  else
1656  {
1657  struct stat st;
1658 
1659  progress_vals[1] = PROGRESS_COPY_TYPE_FILE;
1660  cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
1661  if (cstate->copy_file == NULL)
1662  {
1663  /* copy errno because ereport subfunctions might change it */
1664  int save_errno = errno;
1665 
1666  ereport(ERROR,
1668  errmsg("could not open file \"%s\" for reading: %m",
1669  cstate->filename),
1670  (save_errno == ENOENT || save_errno == EACCES) ?
1671  errhint("COPY FROM instructs the PostgreSQL server process to read a file. "
1672  "You may want a client-side facility such as psql's \\copy.") : 0));
1673  }
1674 
1675  if (fstat(fileno(cstate->copy_file), &st))
1676  ereport(ERROR,
1678  errmsg("could not stat file \"%s\": %m",
1679  cstate->filename)));
1680 
1681  if (S_ISDIR(st.st_mode))
1682  ereport(ERROR,
1683  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1684  errmsg("\"%s\" is a directory", cstate->filename)));
1685 
1686  progress_vals[2] = st.st_size;
1687  }
1688  }
1689 
1690  pgstat_progress_update_multi_param(3, progress_cols, progress_vals);
1691 
1692  if (cstate->opts.binary)
1693  {
1694  /* Read and verify binary header */
1695  ReceiveCopyBinaryHeader(cstate);
1696  }
1697 
1698  /* create workspace for CopyReadAttributes results */
1699  if (!cstate->opts.binary)
1700  {
1701  AttrNumber attr_count = list_length(cstate->attnumlist);
1702 
1703  cstate->max_fields = attr_count;
1704  cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
1705  }
1706 
1707  MemoryContextSwitchTo(oldcontext);
1708 
1709  return cstate;
1710 }
1711 
1712 /*
1713  * Clean up storage and release resources for COPY FROM.
1714  */
1715 void
1717 {
1718  /* No COPY FROM related resources except memory. */
1719  if (cstate->is_program)
1720  {
1721  ClosePipeFromProgram(cstate);
1722  }
1723  else
1724  {
1725  if (cstate->filename != NULL && FreeFile(cstate->copy_file))
1726  ereport(ERROR,
1728  errmsg("could not close file \"%s\": %m",
1729  cstate->filename)));
1730  }
1731 
1733 
1735  pfree(cstate);
1736 }
1737 
1738 /*
1739  * Closes the pipe from an external program, checking the pclose() return code.
1740  */
1741 static void
1743 {
1744  int pclose_rc;
1745 
1746  Assert(cstate->is_program);
1747 
1748  pclose_rc = ClosePipeStream(cstate->copy_file);
1749  if (pclose_rc == -1)
1750  ereport(ERROR,
1752  errmsg("could not close pipe to external command: %m")));
1753  else if (pclose_rc != 0)
1754  {
1755  /*
1756  * If we ended a COPY FROM PROGRAM before reaching EOF, then it's
1757  * expectable for the called program to fail with SIGPIPE, and we
1758  * should not report that as an error. Otherwise, SIGPIPE indicates a
1759  * problem.
1760  */
1761  if (!cstate->raw_reached_eof &&
1762  wait_result_is_signal(pclose_rc, SIGPIPE))
1763  return;
1764 
1765  ereport(ERROR,
1766  (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1767  errmsg("program \"%s\" failed",
1768  cstate->filename),
1769  errdetail_internal("%s", wait_result_to_str(pclose_rc))));
1770  }
1771 }
int16 AttrNumber
Definition: attnum.h:21
List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:722
void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)
Definition: copy.c:405
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:730
#define PG_BINARY_R
Definition: c.h:1262
#define InvalidSubTransactionId
Definition: c.h:642
uint32 CommandId
Definition: c.h:650
bool contain_volatile_functions_not_nextval(Node *clause)
Definition: clauses.c:555
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:448
static void CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copyfrom.c:242
static CopyMultiInsertBuffer * CopyMultiInsertBufferInit(ResultRelInfo *rri)
Definition: copyfrom.c:225
static void CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, CopyFromState cstate, EState *estate, CommandId mycid, int ti_options)
Definition: copyfrom.c:262
static void CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri, int64 *processed)
Definition: copyfrom.c:524
static void CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, TupleTableSlot *slot, int tuplen, uint64 lineno)
Definition: copyfrom.c:609
static void CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
Definition: copyfrom.c:571
#define MAX_PARTITION_BUFFERS
Definition: copyfrom.c:74
struct CopyMultiInsertInfo CopyMultiInsertInfo
#define MAX_BUFFERED_TUPLES
Definition: copyfrom.c:65
static bool CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo)
Definition: copyfrom.c:287
CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *whereClause, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
Definition: copyfrom.c:1339
static void CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, CopyMultiInsertBuffer *buffer, int64 *processed)
Definition: copyfrom.c:308
static TupleTableSlot * CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copyfrom.c:590
static void ClosePipeFromProgram(CopyFromState cstate)
Definition: copyfrom.c:1742
#define MAX_BUFFERED_BYTES
Definition: copyfrom.c:71
static void CopyMultiInsertBufferCleanup(CopyMultiInsertInfo *miinfo, CopyMultiInsertBuffer *buffer)
Definition: copyfrom.c:482
uint64 CopyFrom(CopyFromState cstate)
Definition: copyfrom.c:632
void EndCopyFrom(CopyFromState cstate)
Definition: copyfrom.c:1716
static char * limit_printout_length(const char *str)
Definition: copyfrom.c:195
static bool CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo)
Definition: copyfrom.c:299
struct CopyMultiInsertBuffer CopyMultiInsertBuffer
#define MAX_COPY_DATA_DISPLAY
void CopyFromErrorCallback(void *arg)
Definition: copyfrom.c:116
CopyInsertMethod
@ CIM_SINGLE
@ CIM_MULTI_CONDITIONAL
@ CIM_MULTI
#define INPUT_BUF_SIZE
@ EOL_UNKNOWN
#define RAW_BUF_SIZE
void ReceiveCopyBinaryHeader(CopyFromState cstate)
void ReceiveCopyBegin(CopyFromState cstate)
bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
@ COPY_FILE
Definition: copyto.c:52
@ COPY_CALLBACK
Definition: copyto.c:54
@ DestRemote
Definition: dest.h:89
struct cursor * cur
Definition: ecpg.c:28
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1229
int errcode_for_file_access(void)
Definition: elog.c:881
ErrorContextCallback * error_context_stack
Definition: elog.c:95
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 errcontext
Definition: elog.h:196
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:210
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:124
List * ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool update, bool noDupErr, bool *specConflict, List *arbiterIndexes)
Definition: execIndexing.c:284
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:156
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition: execMain.c:1779
void ExecCloseResultRelations(EState *estate)
Definition: execMain.c:1504
void ExecCloseRangeTableRelations(EState *estate)
Definition: execMain.c:1564
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1903
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
Definition: execMain.c:988
ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, Relation rel)
void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute)
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1191
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1552
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1254
void ExecInitRangeTable(EState *estate, List *rangeTable)
Definition: execUtils.c:758
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition: execUtils.c:841
EState * CreateExecutorState(void)
Definition: execUtils.c:93
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Definition: execUtils.c:1267
void FreeExecutorState(EState *estate)
Definition: execUtils.c:193
#define ResetPerTupleExprContext(estate)
Definition: executor.h:547
#define GetPerTupleExprContext(estate)
Definition: executor.h:538
#define GetPerTupleMemoryContext(estate)
Definition: executor.h:543
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:401
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2383
int ClosePipeStream(FILE *file)
Definition: fd.c:2791
int FreeFile(FILE *file)
Definition: fd.c:2581
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2486
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
Definition: heapam.c:1919
BulkInsertState GetBulkInsertState(void)
Definition: heapam.c:1893
void FreeBulkInsertState(BulkInsertState bistate)
Definition: heapam.c:1907
struct CopyFromStateData * CopyFromState
Definition: copy.h:65
int(* copy_data_source_cb)(void *outbuf, int minread, int maxread)
Definition: copy.h:68
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:338
List * list_delete_first(List *list)
Definition: list.c:942
void list_free(List *list)
Definition: list.c:1545
bool list_member_int(const List *list, int datum)
Definition: list.c:701
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2832
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2898
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1084
int pg_get_client_encoding(void)
Definition: mbutils.c:337
char * pstrdup(const char *in)
Definition: mcxt.c:1624
void pfree(void *pointer)
Definition: mcxt.c:1436
void * palloc0(Size size)
Definition: mcxt.c:1241
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:387
void * palloc(Size size)
Definition: mcxt.c:1210
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
Definition: namespace.c:3753
void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, CmdType cmdtype)
@ CMD_INSERT
Definition: nodes.h:278
#define makeNode(_type_)
Definition: nodes.h:176
#define castNode(_type_, nodeptr)
Definition: nodes.h:197
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
int16 attnum
Definition: pg_attribute.h:83
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
void * arg
const void size_t len
static char * filename
Definition: pg_dumpall.c:119
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define lfirst_int(lc)
Definition: pg_list.h:173
#define linitial(l)
Definition: pg_list.h:178
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
Expr * expression_planner(Expr *expr)
Definition: planner.c:6434
bool ThereAreNoReadyPortals(void)
Definition: portalmem.c:1169
CommandDest whereToSendOutput
Definition: postgres.c:84
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define PROGRESS_COPY_COMMAND
Definition: progress.h:141
#define PROGRESS_COPY_TYPE_FILE
Definition: progress.h:149
#define PROGRESS_COPY_COMMAND_FROM
Definition: progress.h:145
#define PROGRESS_COPY_TUPLES_PROCESSED
Definition: progress.h:139
#define PROGRESS_COPY_TUPLES_EXCLUDED
Definition: progress.h:140
#define PROGRESS_COPY_TYPE
Definition: progress.h:142
#define PROGRESS_COPY_TYPE_PROGRAM
Definition: progress.h:150
#define PROGRESS_COPY_BYTES_TOTAL
Definition: progress.h:138
#define PROGRESS_COPY_TYPE_CALLBACK
Definition: progress.h:152
#define PROGRESS_COPY_TYPE_PIPE
Definition: progress.h:151
#define RelationGetRelid(relation)
Definition: rel.h:501
#define RelationGetDescr(relation)
Definition: rel.h:527
#define RelationGetRelationName(relation)
Definition: rel.h:535
Node * build_column_default(Relation rel, int attrno)
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition: snapmgr.c:1623
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:457
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
bool freeze
Definition: copy.h:44
bool binary
Definition: copy.h:43
bool convert_selectively
Definition: copy.h:60
List * force_null
Definition: copy.h:58
List * convert_select
Definition: copy.h:61
bool * force_notnull_flags
Definition: copy.h:57
int file_encoding
Definition: copy.h:41
bool * force_null_flags
Definition: copy.h:59
List * force_notnull
Definition: copy.h:56
ExprState ** defexprs
copy_data_source_cb data_source_cb
StringInfoData line_buf
CopyFormatOptions opts
StringInfoData attribute_buf
TransitionCaptureState * transition_capture
MemoryContext copycontext
const char * cur_attval
const char * cur_attname
const char * cur_relname
TupleTableSlot * slots[MAX_BUFFERED_TUPLES]
Definition: copyfrom.c:79
ResultRelInfo * resultRelInfo
Definition: copyfrom.c:80
uint64 linenos[MAX_BUFFERED_TUPLES]
Definition: copyfrom.c:84
BulkInsertState bistate
Definition: copyfrom.c:81
EState * estate
Definition: copyfrom.c:99
CommandId mycid
Definition: copyfrom.c:100
List * multiInsertBuffers
Definition: copyfrom.c:95
CopyFromState cstate
Definition: copyfrom.c:98
List * es_rteperminfos
Definition: execnodes.h:620
List * es_tupleTable
Definition: execnodes.h:658
struct ErrorContextCallback * previous
Definition: elog.h:295
void(* callback)(void *arg)
Definition: elog.h:296
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:247
EndForeignInsert_function EndForeignInsert
Definition: fdwapi.h:239
BeginForeignInsert_function BeginForeignInsert
Definition: fdwapi.h:238
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:232
ExecForeignBatchInsert_function ExecForeignBatchInsert
Definition: fdwapi.h:233
GetForeignModifyBatchSize_function GetForeignModifyBatchSize
Definition: fdwapi.h:234
Definition: fmgr.h:57
Definition: pg_list.h:54
CmdType operation
Definition: execnodes.h:1259
ResultRelInfo * resultRelInfo
Definition: execnodes.h:1263
PlanState ps
Definition: execnodes.h:1258
ResultRelInfo * rootResultRelInfo
Definition: execnodes.h:1271
struct TransitionCaptureState * mt_transition_capture
Definition: execnodes.h:1297
Definition: nodes.h:129
List * p_rteperminfos
Definition: parse_node.h:194
List * p_rtable
Definition: parse_node.h:193
Plan * plan
Definition: execnodes.h:1031
EState * state
Definition: execnodes.h:1033
SubTransactionId rd_firstRelfilelocatorSubid
Definition: rel.h:105
TriggerDesc * trigdesc
Definition: rel.h:116
TupleDesc rd_att
Definition: rel.h:111
SubTransactionId rd_newRelfilelocatorSubid
Definition: rel.h:103
SubTransactionId rd_createSubid
Definition: rel.h:102
Form_pg_class rd_rel
Definition: rel.h:110
TupleTableSlot * ri_PartitionTupleSlot
Definition: execnodes.h:571
int ri_NumIndices
Definition: execnodes.h:451
Relation ri_RelationDesc
Definition: execnodes.h:448
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition: execnodes.h:574
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:478
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:495
int ri_BatchSize
Definition: execnodes.h:506
TupleTableSlot * tcs_original_insert_tuple
Definition: trigger.h:76
bool trig_insert_instead_row
Definition: reltrigger.h:58
bool trig_insert_after_row
Definition: reltrigger.h:57
bool trig_insert_new_table
Definition: reltrigger.h:75
bool trig_insert_before_row
Definition: reltrigger.h:56
bool has_generated_stored
Definition: tupdesc.h:45
AttrMap * attrMap
Definition: tupconvert.h:28
TupleConstr * constr
Definition: tupdesc.h:85
Oid tts_tableOid
Definition: tuptable.h:131
bool * tts_isnull
Definition: tuptable.h:128
Datum * tts_values
Definition: tuptable.h:126
__int64 st_size
Definition: win32_port.h:275
unsigned short st_mode
Definition: win32_port.h:270
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
#define TABLE_INSERT_FROZEN
Definition: tableam.h:237
#define TABLE_INSERT_SKIP_FSM
Definition: tableam.h:236
static void table_finish_bulk_insert(Relation rel, int options)
Definition: tableam.h:1574
static void table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:1436
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:1381
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
Definition: trigger.c:2399
bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition: trigger.c:2463
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition: trigger.c:2556
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
Definition: trigger.c:2539
TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
Definition: trigger.c:4818
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
Definition: trigger.c:2450
void AfterTriggerEndQuery(EState *estate)
Definition: trigger.c:4974
void AfterTriggerBeginQuery(void)
Definition: trigger.c:4954
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:192
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:433
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:483
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:451
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33
bool wait_result_is_signal(int exit_status, int signum)
Definition: wait_error.c:102
#define SIGPIPE
Definition: win32_port.h:181
#define S_ISDIR(m)
Definition: win32_port.h:327
#define fstat
Definition: win32_port.h:285
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:780
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:818