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