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