PostgreSQL Source Code  git master
copy.h File Reference
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "tcop/dest.h"
Include dependency graph for copy.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct CopyStateDataCopyState
 
typedef int(* copy_data_source_cb) (void *outbuf, int minread, int maxread)
 

Functions

void DoCopy (ParseState *state, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
 
void ProcessCopyOptions (ParseState *pstate, CopyState cstate, bool is_from, List *options)
 
CopyState BeginCopyFrom (ParseState *pstate, Relation rel, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
 
void EndCopyFrom (CopyState cstate)
 
bool NextCopyFrom (CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls)
 
bool NextCopyFromRawFields (CopyState cstate, char ***fields, int *nfields)
 
void CopyFromErrorCallback (void *arg)
 
uint64 CopyFrom (CopyState cstate)
 
DestReceiverCreateCopyDestReceiver (void)
 

Typedef Documentation

◆ copy_data_source_cb

typedef int(* copy_data_source_cb) (void *outbuf, int minread, int maxread)

Definition at line 24 of file copy.h.

◆ CopyState

typedef struct CopyStateData* CopyState

Definition at line 23 of file copy.h.

Function Documentation

◆ BeginCopyFrom()

CopyState BeginCopyFrom ( ParseState pstate,
Relation  rel,
const char *  filename,
bool  is_program,
copy_data_source_cb  data_source_cb,
List attnamelist,
List options 
)

Definition at line 3387 of file copy.c.

References AllocateFile(), Assert, attnum, CopyStateData::attnumlist, CopyStateData::attribute_buf, BeginCopy(), CopyStateData::binary, BinarySignature, build_column_default(), contain_volatile_functions_not_nextval(), COPY_CALLBACK, CopyStateData::copy_dest, CopyStateData::copy_file, CopyStateData::copycontext, CopyGetData(), CopyGetInt32(), CopyStateData::cur_attname, CopyStateData::cur_attval, CopyStateData::cur_lineno, CopyStateData::cur_relname, CopyStateData::data_source_cb, CopyStateData::defexprs, CopyStateData::defmap, DestRemote, CopyStateData::eol_type, EOL_UNKNOWN, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, ExecInitExpr(), expression_planner(), CopyStateData::filename, fmgr_info(), getTypeBinaryInputInfo(), getTypeInputInfo(), CopyStateData::in_functions, initStringInfo(), InvalidOid, CopyStateData::is_program, CopyStateData::line_buf, CopyStateData::line_buf_converted, list_length(), list_member_int(), CopyStateData::max_fields, MemoryContextSwitchTo(), TupleDescData::natts, CopyStateData::num_defaults, OpenPipeStream(), ParseState::p_rtable, palloc(), PG_BINARY_R, pstrdup(), CopyStateData::range_table, CopyStateData::raw_buf, CopyStateData::raw_buf_index, CopyStateData::raw_buf_len, RAW_BUF_SIZE, CopyStateData::raw_fields, CopyStateData::reached_eof, ReceiveCopyBegin(), CopyStateData::rel, RelationGetDescr, RelationGetRelationName, S_ISDIR, stat, TupleDescAttr, CopyStateData::typioparams, CopyStateData::volatile_defexprs, and whereToSendOutput.

Referenced by copy_table(), DoCopy(), file_acquire_sample_rows(), fileBeginForeignScan(), and fileReScanForeignScan().

3394 {
3395  CopyState cstate;
3396  bool pipe = (filename == NULL);
3397  TupleDesc tupDesc;
3398  AttrNumber num_phys_attrs,
3399  num_defaults;
3400  FmgrInfo *in_functions;
3401  Oid *typioparams;
3402  int attnum;
3403  Oid in_func_oid;
3404  int *defmap;
3405  ExprState **defexprs;
3406  MemoryContext oldcontext;
3407  bool volatile_defexprs;
3408 
3409  cstate = BeginCopy(pstate, true, rel, NULL, InvalidOid, attnamelist, options);
3410  oldcontext = MemoryContextSwitchTo(cstate->copycontext);
3411 
3412  /* Initialize state variables */
3413  cstate->reached_eof = false;
3414  cstate->eol_type = EOL_UNKNOWN;
3415  cstate->cur_relname = RelationGetRelationName(cstate->rel);
3416  cstate->cur_lineno = 0;
3417  cstate->cur_attname = NULL;
3418  cstate->cur_attval = NULL;
3419 
3420  /* Set up variables to avoid per-attribute overhead. */
3421  initStringInfo(&cstate->attribute_buf);
3422  initStringInfo(&cstate->line_buf);
3423  cstate->line_buf_converted = false;
3424  cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
3425  cstate->raw_buf_index = cstate->raw_buf_len = 0;
3426 
3427  /* Assign range table, we'll need it in CopyFrom. */
3428  if (pstate)
3429  cstate->range_table = pstate->p_rtable;
3430 
3431  tupDesc = RelationGetDescr(cstate->rel);
3432  num_phys_attrs = tupDesc->natts;
3433  num_defaults = 0;
3434  volatile_defexprs = false;
3435 
3436  /*
3437  * Pick up the required catalog information for each attribute in the
3438  * relation, including the input function, the element type (to pass to
3439  * the input function), and info about defaults and constraints. (Which
3440  * input function we use depends on text/binary format choice.)
3441  */
3442  in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
3443  typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
3444  defmap = (int *) palloc(num_phys_attrs * sizeof(int));
3445  defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
3446 
3447  for (attnum = 1; attnum <= num_phys_attrs; attnum++)
3448  {
3449  Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
3450 
3451  /* We don't need info for dropped attributes */
3452  if (att->attisdropped)
3453  continue;
3454 
3455  /* Fetch the input function and typioparam info */
3456  if (cstate->binary)
3457  getTypeBinaryInputInfo(att->atttypid,
3458  &in_func_oid, &typioparams[attnum - 1]);
3459  else
3460  getTypeInputInfo(att->atttypid,
3461  &in_func_oid, &typioparams[attnum - 1]);
3462  fmgr_info(in_func_oid, &in_functions[attnum - 1]);
3463 
3464  /* Get default info if needed */
3465  if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated)
3466  {
3467  /* attribute is NOT to be copied from input */
3468  /* use default value if one exists */
3469  Expr *defexpr = (Expr *) build_column_default(cstate->rel,
3470  attnum);
3471 
3472  if (defexpr != NULL)
3473  {
3474  /* Run the expression through planner */
3475  defexpr = expression_planner(defexpr);
3476 
3477  /* Initialize executable expression in copycontext */
3478  defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
3479  defmap[num_defaults] = attnum - 1;
3480  num_defaults++;
3481 
3482  /*
3483  * If a default expression looks at the table being loaded,
3484  * then it could give the wrong answer when using
3485  * multi-insert. Since database access can be dynamic this is
3486  * hard to test for exactly, so we use the much wider test of
3487  * whether the default expression is volatile. We allow for
3488  * the special case of when the default expression is the
3489  * nextval() of a sequence which in this specific case is
3490  * known to be safe for use with the multi-insert
3491  * optimization. Hence we use this special case function
3492  * checker rather than the standard check for
3493  * contain_volatile_functions().
3494  */
3495  if (!volatile_defexprs)
3496  volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr);
3497  }
3498  }
3499  }
3500 
3501  /* We keep those variables in cstate. */
3502  cstate->in_functions = in_functions;
3503  cstate->typioparams = typioparams;
3504  cstate->defmap = defmap;
3505  cstate->defexprs = defexprs;
3506  cstate->volatile_defexprs = volatile_defexprs;
3507  cstate->num_defaults = num_defaults;
3508  cstate->is_program = is_program;
3509 
3510  if (data_source_cb)
3511  {
3512  cstate->copy_dest = COPY_CALLBACK;
3513  cstate->data_source_cb = data_source_cb;
3514  }
3515  else if (pipe)
3516  {
3517  Assert(!is_program); /* the grammar does not allow this */
3519  ReceiveCopyBegin(cstate);
3520  else
3521  cstate->copy_file = stdin;
3522  }
3523  else
3524  {
3525  cstate->filename = pstrdup(filename);
3526 
3527  if (cstate->is_program)
3528  {
3529  cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R);
3530  if (cstate->copy_file == NULL)
3531  ereport(ERROR,
3533  errmsg("could not execute command \"%s\": %m",
3534  cstate->filename)));
3535  }
3536  else
3537  {
3538  struct stat st;
3539 
3540  cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
3541  if (cstate->copy_file == NULL)
3542  {
3543  /* copy errno because ereport subfunctions might change it */
3544  int save_errno = errno;
3545 
3546  ereport(ERROR,
3548  errmsg("could not open file \"%s\" for reading: %m",
3549  cstate->filename),
3550  (save_errno == ENOENT || save_errno == EACCES) ?
3551  errhint("COPY FROM instructs the PostgreSQL server process to read a file. "
3552  "You may want a client-side facility such as psql's \\copy.") : 0));
3553  }
3554 
3555  if (fstat(fileno(cstate->copy_file), &st))
3556  ereport(ERROR,
3558  errmsg("could not stat file \"%s\": %m",
3559  cstate->filename)));
3560 
3561  if (S_ISDIR(st.st_mode))
3562  ereport(ERROR,
3563  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3564  errmsg("\"%s\" is a directory", cstate->filename)));
3565  }
3566  }
3567 
3568  if (cstate->binary)
3569  {
3570  /* Read and verify binary header */
3571  char readSig[11];
3572  int32 tmp;
3573 
3574  /* Signature */
3575  if (CopyGetData(cstate, readSig, 11, 11) != 11 ||
3576  memcmp(readSig, BinarySignature, 11) != 0)
3577  ereport(ERROR,
3578  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3579  errmsg("COPY file signature not recognized")));
3580  /* Flags field */
3581  if (!CopyGetInt32(cstate, &tmp))
3582  ereport(ERROR,
3583  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3584  errmsg("invalid COPY file header (missing flags)")));
3585  if ((tmp & (1 << 16)) != 0)
3586  ereport(ERROR,
3587  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3588  errmsg("invalid COPY file header (WITH OIDS)")));
3589  tmp &= ~(1 << 16);
3590  if ((tmp >> 16) != 0)
3591  ereport(ERROR,
3592  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3593  errmsg("unrecognized critical flags in COPY file header")));
3594  /* Header extension length */
3595  if (!CopyGetInt32(cstate, &tmp) ||
3596  tmp < 0)
3597  ereport(ERROR,
3598  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3599  errmsg("invalid COPY file header (missing length)")));
3600  /* Skip extension header, if present */
3601  while (tmp-- > 0)
3602  {
3603  if (CopyGetData(cstate, readSig, 1, 1) != 1)
3604  ereport(ERROR,
3605  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3606  errmsg("invalid COPY file header (wrong length)")));
3607  }
3608  }
3609 
3610  /* create workspace for CopyReadAttributes results */
3611  if (!cstate->binary)
3612  {
3613  AttrNumber attr_count = list_length(cstate->attnumlist);
3614 
3615  cstate->max_fields = attr_count;
3616  cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
3617  }
3618 
3619  MemoryContextSwitchTo(oldcontext);
3620 
3621  return cstate;
3622 }
Definition: fmgr.h:56
List * range_table
Definition: copy.c:184
static CopyState BeginCopy(ParseState *pstate, bool is_from, Relation rel, RawStmt *raw_query, Oid queryRelId, List *attnamelist, List *options)
Definition: copy.c:1461
bool contain_volatile_functions_not_nextval(Node *clause)
Definition: clauses.c:774
static bool CopyGetInt32(CopyState cstate, int32 *val)
Definition: copy.c:739
int errhint(const char *fmt,...)
Definition: elog.c:974
char ** raw_fields
Definition: copy.c:202
bool binary
Definition: copy.c:136
#define RelationGetDescr(relation)
Definition: rel.h:445
AttrNumber num_defaults
Definition: copy.c:178
FmgrInfo * in_functions
Definition: copy.c:179
List * attnumlist
Definition: copy.c:132
char * filename
Definition: copy.c:133
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1186
static void ReceiveCopyBegin(CopyState cstate)
Definition: copy.c:435
Expr * expression_planner(Expr *expr)
Definition: planner.c:6046
StringInfoData line_buf
Definition: copy.c:211
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:525
int raw_buf_index
Definition: copy.c:224
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
bool volatile_defexprs
Definition: copy.c:183
#define PG_BINARY_R
Definition: c.h:1193
bool line_buf_converted
Definition: copy.c:212
signed int int32
Definition: c.h:346
CopyDest copy_dest
Definition: copy.c:117
uint64 cur_lineno
Definition: copy.c:160
const char * cur_attname
Definition: copy.c:161
Relation rel
Definition: copy.c:130
MemoryContext copycontext
Definition: copy.c:167
copy_data_source_cb data_source_cb
Definition: copy.c:135
#define ERROR
Definition: elog.h:43
static int CopyGetData(CopyState cstate, void *databuf, int minread, int maxread)
Definition: copy.c:611
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:124
bool list_member_int(const List *list, int datum)
Definition: list.c:655
char * raw_buf
Definition: copy.c:223
ExprState ** defexprs
Definition: copy.c:182
const char * cur_relname
Definition: copy.c:159
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2205
#define RelationGetRelationName(relation)
Definition: rel.h:453
static const char BinarySignature[11]
Definition: copy.c:350
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
int raw_buf_len
Definition: copy.c:225
int max_fields
Definition: copy.c:201
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2308
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2707
#define ereport(elevel, rest)
Definition: elog.h:141
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define stat(a, b)
Definition: win32_port.h:255
Oid * typioparams
Definition: copy.c:180
bool is_program
Definition: copy.c:134
Node * build_column_default(Relation rel, int attrno)
#define RAW_BUF_SIZE
Definition: copy.c:222
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
EolType eol_type
Definition: copy.c:124
#define Assert(condition)
Definition: c.h:732
bool reached_eof
Definition: copy.c:122
static int list_length(const List *l)
Definition: pg_list.h:169
#define S_ISDIR(m)
Definition: win32_port.h:296
static char * filename
Definition: pg_dumpall.c:91
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
FILE * copy_file
Definition: copy.c:118
StringInfoData attribute_buf
Definition: copy.c:197
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:121
const char * cur_attval
Definition: copy.c:162
CommandDest whereToSendOutput
Definition: postgres.c:90
int16 AttrNumber
Definition: attnum.h:21
int * defmap
Definition: copy.c:181
List * p_rtable
Definition: parse_node.h:177

◆ CopyFrom()

uint64 CopyFrom ( CopyState  cstate)

Definition at line 2658 of file copy.c.

References AfterTriggerBeginQuery(), AfterTriggerEndQuery(), ErrorContextCallback::arg, Assert, TupleConversionMap::attrMap, FdwRoutine::BeginForeignInsert, ErrorContextCallback::callback, castNode, CHECK_FOR_INTERRUPTS, CheckValidResultRel(), CIM_MULTI, CIM_MULTI_CONDITIONAL, CIM_SINGLE, CMD_INSERT, TupleDescData::constr, contain_volatile_functions(), CopyStateData::copy_dest, COPY_OLD_FE, CopyFromErrorCallback(), CopyMultiInsertInfoCleanup(), CopyMultiInsertInfoFlush(), CopyMultiInsertInfoInit(), CopyMultiInsertInfoIsEmpty(), CopyMultiInsertInfoIsFull(), CopyMultiInsertInfoNextFreeSlot(), CopyMultiInsertInfoSetupBuffer(), CopyMultiInsertInfoStore(), CreateExecutorState(), CopyStateData::cur_lineno, CurrentMemoryContext, ExprContext::ecxt_scantuple, FdwRoutine::EndForeignInsert, ereport, errcode(), errhint(), errmsg(), ERROR, error_context_stack, EState::es_num_result_relations, EState::es_result_relation_info, EState::es_result_relations, EState::es_tupleTable, ExecARInsertTriggers(), ExecASInsertTriggers(), ExecBRInsertTriggers(), ExecBSInsertTriggers(), ExecCleanUpTriggerState(), ExecCleanupTupleRouting(), ExecClearTuple(), ExecCloseIndices(), ExecComputeStoredGenerated(), ExecConstraints(), ExecCopySlot(), ExecFindPartition(), FdwRoutine::ExecForeignInsert, ExecInitQual(), ExecInitRangeTable(), ExecInsertIndexTuples(), ExecIRInsertTriggers(), ExecMaterializeSlot(), ExecOpenIndices(), ExecPartitionCheck(), ExecQual(), ExecResetTupleTable(), ExecSetupPartitionTupleRouting(), ExecStoreVirtualTuple(), execute_attr_map_slot(), FreeBulkInsertState(), FreeExecutorState(), CopyStateData::freeze, GetBulkInsertState(), GetCurrentCommandId(), GetCurrentSubTransactionId(), GetPerTupleExprContext, GetPerTupleMemoryContext, TupleConstr::has_generated_stored, InitResultRelInfo(), InvalidateCatalogSnapshot(), InvalidSubTransactionId, StringInfoData::len, CopyStateData::line_buf, list_free(), makeNode, MakeTransitionCaptureState(), MemoryContextSwitchTo(), ModifyTableState::mt_transition_capture, NextCopyFrom(), NIL, ModifyTableState::operation, PartitionRoutingInfo::pi_PartitionToRootMap, PartitionRoutingInfo::pi_PartitionTupleSlot, PartitionRoutingInfo::pi_RootToPartitionMap, PlanState::plan, pq_endmsgread(), ErrorContextCallback::previous, ModifyTableState::ps, CopyStateData::qualexpr, CopyStateData::range_table, RelationData::rd_att, RelationData::rd_createSubid, RelationData::rd_newRelfilenodeSubid, RelationData::rd_rel, CopyStateData::rel, RelationGetRelationName, RelationGetRelid, ReleaseBulkInsertStatePin(), ResetPerTupleExprContext, ModifyTableState::resultRelInfo, ResultRelInfo::ri_CopyMultiInsertBuffer, ResultRelInfo::ri_FdwRoutine, ResultRelInfo::ri_NumIndices, ResultRelInfo::ri_PartitionCheck, ResultRelInfo::ri_PartitionInfo, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigDesc, PlanState::state, TABLE_INSERT_FROZEN, TABLE_INSERT_SKIP_FSM, TABLE_INSERT_SKIP_WAL, table_slot_create(), table_tuple_insert(), TransitionCaptureState::tcs_map, TransitionCaptureState::tcs_original_insert_tuple, ThereAreNoPriorRegisteredSnapshots(), ThereAreNoReadyPortals(), CopyStateData::transition_capture, TriggerDesc::trig_insert_before_row, TriggerDesc::trig_insert_instead_row, TriggerDesc::trig_insert_new_table, RelationData::trigdesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tableOid, TupleTableSlot::tts_values, CopyStateData::volatile_defexprs, CopyStateData::whereClause, and XLogIsNeeded.

Referenced by copy_table(), and DoCopy().

2659 {
2660  ResultRelInfo *resultRelInfo;
2661  ResultRelInfo *target_resultRelInfo;
2662  ResultRelInfo *prevResultRelInfo = NULL;
2663  EState *estate = CreateExecutorState(); /* for ExecConstraints() */
2664  ModifyTableState *mtstate;
2665  ExprContext *econtext;
2666  TupleTableSlot *singleslot = NULL;
2667  MemoryContext oldcontext = CurrentMemoryContext;
2668 
2669  PartitionTupleRouting *proute = NULL;
2670  ErrorContextCallback errcallback;
2671  CommandId mycid = GetCurrentCommandId(true);
2672  int ti_options = 0; /* start with default options for insert */
2673  BulkInsertState bistate = NULL;
2674  CopyInsertMethod insertMethod;
2675  CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
2676  uint64 processed = 0;
2677  bool has_before_insert_row_trig;
2678  bool has_instead_insert_row_trig;
2679  bool leafpart_use_multi_insert = false;
2680 
2681  Assert(cstate->rel);
2682 
2683  /*
2684  * The target must be a plain, foreign, or partitioned relation, or have
2685  * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
2686  * allowed on views, so we only hint about them in the view case.)
2687  */
2688  if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
2689  cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
2690  cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
2691  !(cstate->rel->trigdesc &&
2693  {
2694  if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
2695  ereport(ERROR,
2696  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2697  errmsg("cannot copy to view \"%s\"",
2698  RelationGetRelationName(cstate->rel)),
2699  errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
2700  else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
2701  ereport(ERROR,
2702  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2703  errmsg("cannot copy to materialized view \"%s\"",
2704  RelationGetRelationName(cstate->rel))));
2705  else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
2706  ereport(ERROR,
2707  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2708  errmsg("cannot copy to sequence \"%s\"",
2709  RelationGetRelationName(cstate->rel))));
2710  else
2711  ereport(ERROR,
2712  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2713  errmsg("cannot copy to non-table relation \"%s\"",
2714  RelationGetRelationName(cstate->rel))));
2715  }
2716 
2717  /*----------
2718  * Check to see if we can avoid writing WAL
2719  *
2720  * If archive logging/streaming is not enabled *and* either
2721  * - table was created in same transaction as this COPY
2722  * - data is being written to relfilenode created in this transaction
2723  * then we can skip writing WAL. It's safe because if the transaction
2724  * doesn't commit, we'll discard the table (or the new relfilenode file).
2725  * If it does commit, we'll have done the table_finish_bulk_insert() at
2726  * the bottom of this routine first.
2727  *
2728  * As mentioned in comments in utils/rel.h, the in-same-transaction test
2729  * is not always set correctly, since in rare cases rd_newRelfilenodeSubid
2730  * can be cleared before the end of the transaction. The exact case is
2731  * when a relation sets a new relfilenode twice in same transaction, yet
2732  * the second one fails in an aborted subtransaction, e.g.
2733  *
2734  * BEGIN;
2735  * TRUNCATE t;
2736  * SAVEPOINT save;
2737  * TRUNCATE t;
2738  * ROLLBACK TO save;
2739  * COPY ...
2740  *
2741  * Also, if the target file is new-in-transaction, we assume that checking
2742  * FSM for free space is a waste of time, even if we must use WAL because
2743  * of archiving. This could possibly be wrong, but it's unlikely.
2744  *
2745  * The comments for table_tuple_insert and RelationGetBufferForTuple
2746  * specify that skipping WAL logging is only safe if we ensure that our
2747  * tuples do not go into pages containing tuples from any other
2748  * transactions --- but this must be the case if we have a new table or
2749  * new relfilenode, so we need no additional work to enforce that.
2750  *
2751  * We currently don't support this optimization if the COPY target is a
2752  * partitioned table as we currently only lazily initialize partition
2753  * information when routing the first tuple to the partition. We cannot
2754  * know at this stage if we can perform this optimization. It should be
2755  * possible to improve on this, but it does mean maintaining heap insert
2756  * option flags per partition and setting them when we first open the
2757  * partition.
2758  *
2759  * This optimization is not supported for relation types which do not
2760  * have any physical storage, with foreign tables and views using
2761  * INSTEAD OF triggers entering in this category. Partitioned tables
2762  * are not supported as per the description above.
2763  *----------
2764  */
2765  /* createSubid is creation check, newRelfilenodeSubid is truncation check */
2766  if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) &&
2769  {
2770  ti_options |= TABLE_INSERT_SKIP_FSM;
2771  if (!XLogIsNeeded())
2772  ti_options |= TABLE_INSERT_SKIP_WAL;
2773  }
2774 
2775  /*
2776  * Optimize if new relfilenode was created in this subxact or one of its
2777  * committed children and we won't see those rows later as part of an
2778  * earlier scan or command. The subxact test ensures that if this subxact
2779  * aborts then the frozen rows won't be visible after xact cleanup. Note
2780  * that the stronger test of exactly which subtransaction created it is
2781  * crucial for correctness of this optimization. The test for an earlier
2782  * scan or command tolerates false negatives. FREEZE causes other sessions
2783  * to see rows they would not see under MVCC, and a false negative merely
2784  * spreads that anomaly to the current session.
2785  */
2786  if (cstate->freeze)
2787  {
2788  /*
2789  * We currently disallow COPY FREEZE on partitioned tables. The
2790  * reason for this is that we've simply not yet opened the partitions
2791  * to determine if the optimization can be applied to them. We could
2792  * go and open them all here, but doing so may be quite a costly
2793  * overhead for small copies. In any case, we may just end up routing
2794  * tuples to a small number of partitions. It seems better just to
2795  * raise an ERROR for partitioned tables.
2796  */
2797  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2798  {
2799  ereport(ERROR,
2800  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2801  errmsg("cannot perform COPY FREEZE on a partitioned table")));
2802  }
2803 
2804  /*
2805  * Tolerate one registration for the benefit of FirstXactSnapshot.
2806  * Scan-bearing queries generally create at least two registrations,
2807  * though relying on that is fragile, as is ignoring ActiveSnapshot.
2808  * Clear CatalogSnapshot to avoid counting its registration. We'll
2809  * still detect ongoing catalog scans, each of which separately
2810  * registers the snapshot it uses.
2811  */
2814  ereport(ERROR,
2815  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2816  errmsg("cannot perform COPY FREEZE because of prior transaction activity")));
2817 
2818  if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() &&
2820  ereport(ERROR,
2821  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2822  errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction")));
2823 
2824  ti_options |= TABLE_INSERT_FROZEN;
2825  }
2826 
2827  /*
2828  * We need a ResultRelInfo so we can use the regular executor's
2829  * index-entry-making machinery. (There used to be a huge amount of code
2830  * here that basically duplicated execUtils.c ...)
2831  */
2832  resultRelInfo = makeNode(ResultRelInfo);
2833  InitResultRelInfo(resultRelInfo,
2834  cstate->rel,
2835  1, /* must match rel's position in range_table */
2836  NULL,
2837  0);
2838  target_resultRelInfo = resultRelInfo;
2839 
2840  /* Verify the named relation is a valid target for INSERT */
2841  CheckValidResultRel(resultRelInfo, CMD_INSERT);
2842 
2843  ExecOpenIndices(resultRelInfo, false);
2844 
2845  estate->es_result_relations = resultRelInfo;
2846  estate->es_num_result_relations = 1;
2847  estate->es_result_relation_info = resultRelInfo;
2848 
2849  ExecInitRangeTable(estate, cstate->range_table);
2850 
2851  /*
2852  * Set up a ModifyTableState so we can let FDW(s) init themselves for
2853  * foreign-table result relation(s).
2854  */
2855  mtstate = makeNode(ModifyTableState);
2856  mtstate->ps.plan = NULL;
2857  mtstate->ps.state = estate;
2858  mtstate->operation = CMD_INSERT;
2859  mtstate->resultRelInfo = estate->es_result_relations;
2860 
2861  if (resultRelInfo->ri_FdwRoutine != NULL &&
2862  resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
2863  resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate,
2864  resultRelInfo);
2865 
2866  /* Prepare to catch AFTER triggers. */
2868 
2869  /*
2870  * If there are any triggers with transition tables on the named relation,
2871  * we need to be prepared to capture transition tuples.
2872  *
2873  * Because partition tuple routing would like to know about whether
2874  * transition capture is active, we also set it in mtstate, which is
2875  * passed to ExecFindPartition() below.
2876  */
2877  cstate->transition_capture = mtstate->mt_transition_capture =
2879  RelationGetRelid(cstate->rel),
2880  CMD_INSERT);
2881 
2882  /*
2883  * If the named relation is a partitioned table, initialize state for
2884  * CopyFrom tuple routing.
2885  */
2886  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2887  proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel);
2888 
2889  if (cstate->whereClause)
2890  cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
2891  &mtstate->ps);
2892 
2893  /*
2894  * It's generally more efficient to prepare a bunch of tuples for
2895  * insertion, and insert them in one table_multi_insert() call, than call
2896  * table_tuple_insert() separately for every tuple. However, there are a
2897  * number of reasons why we might not be able to do this. These are
2898  * explained below.
2899  */
2900  if (resultRelInfo->ri_TrigDesc != NULL &&
2901  (resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
2902  resultRelInfo->ri_TrigDesc->trig_insert_instead_row))
2903  {
2904  /*
2905  * Can't support multi-inserts when there are any BEFORE/INSTEAD OF
2906  * triggers on the table. Such triggers might query the table we're
2907  * inserting into and act differently if the tuples that have already
2908  * been processed and prepared for insertion are not there.
2909  */
2910  insertMethod = CIM_SINGLE;
2911  }
2912  else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL &&
2913  resultRelInfo->ri_TrigDesc->trig_insert_new_table)
2914  {
2915  /*
2916  * For partitioned tables we can't support multi-inserts when there
2917  * are any statement level insert triggers. It might be possible to
2918  * allow partitioned tables with such triggers in the future, but for
2919  * now, CopyMultiInsertInfoFlush expects that any before row insert
2920  * and statement level insert triggers are on the same relation.
2921  */
2922  insertMethod = CIM_SINGLE;
2923  }
2924  else if (resultRelInfo->ri_FdwRoutine != NULL ||
2925  cstate->volatile_defexprs)
2926  {
2927  /*
2928  * Can't support multi-inserts to foreign tables or if there are any
2929  * volatile default expressions in the table. Similarly to the
2930  * trigger case above, such expressions may query the table we're
2931  * inserting into.
2932  *
2933  * Note: It does not matter if any partitions have any volatile
2934  * default expressions as we use the defaults from the target of the
2935  * COPY command.
2936  */
2937  insertMethod = CIM_SINGLE;
2938  }
2939  else if (contain_volatile_functions(cstate->whereClause))
2940  {
2941  /*
2942  * Can't support multi-inserts if there are any volatile function
2943  * expressions in WHERE clause. Similarly to the trigger case above,
2944  * such expressions may query the table we're inserting into.
2945  */
2946  insertMethod = CIM_SINGLE;
2947  }
2948  else
2949  {
2950  /*
2951  * For partitioned tables, we may still be able to perform bulk
2952  * inserts. However, the possibility of this depends on which types
2953  * of triggers exist on the partition. We must disable bulk inserts
2954  * if the partition is a foreign table or it has any before row insert
2955  * or insert instead triggers (same as we checked above for the parent
2956  * table). Since the partition's resultRelInfos are initialized only
2957  * when we actually need to insert the first tuple into them, we must
2958  * have the intermediate insert method of CIM_MULTI_CONDITIONAL to
2959  * flag that we must later determine if we can use bulk-inserts for
2960  * the partition being inserted into.
2961  */
2962  if (proute)
2963  insertMethod = CIM_MULTI_CONDITIONAL;
2964  else
2965  insertMethod = CIM_MULTI;
2966 
2967  CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate,
2968  estate, mycid, ti_options);
2969  }
2970 
2971  /*
2972  * If not using batch mode (which allocates slots as needed) set up a
2973  * tuple slot too. When inserting into a partitioned table, we also need
2974  * one, even if we might batch insert, to read the tuple in the root
2975  * partition's form.
2976  */
2977  if (insertMethod == CIM_SINGLE || insertMethod == CIM_MULTI_CONDITIONAL)
2978  {
2979  singleslot = table_slot_create(resultRelInfo->ri_RelationDesc,
2980  &estate->es_tupleTable);
2981  bistate = GetBulkInsertState();
2982  }
2983 
2984  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
2985  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
2986 
2987  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
2988  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
2989 
2990  /*
2991  * Check BEFORE STATEMENT insertion triggers. It's debatable whether we
2992  * should do this for COPY, since it's not really an "INSERT" statement as
2993  * such. However, executing these triggers maintains consistency with the
2994  * EACH ROW triggers that we already fire on COPY.
2995  */
2996  ExecBSInsertTriggers(estate, resultRelInfo);
2997 
2998  econtext = GetPerTupleExprContext(estate);
2999 
3000  /* Set up callback to identify error line number */
3001  errcallback.callback = CopyFromErrorCallback;
3002  errcallback.arg = (void *) cstate;
3003  errcallback.previous = error_context_stack;
3004  error_context_stack = &errcallback;
3005 
3006  for (;;)
3007  {
3008  TupleTableSlot *myslot;
3009  bool skip_tuple;
3010 
3012 
3013  /*
3014  * Reset the per-tuple exprcontext. We do this after every tuple, to
3015  * clean-up after expression evaluations etc.
3016  */
3017  ResetPerTupleExprContext(estate);
3018 
3019  /* select slot to (initially) load row into */
3020  if (insertMethod == CIM_SINGLE || proute)
3021  {
3022  myslot = singleslot;
3023  Assert(myslot != NULL);
3024  }
3025  else
3026  {
3027  Assert(resultRelInfo == target_resultRelInfo);
3028  Assert(insertMethod == CIM_MULTI);
3029 
3030  myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
3031  resultRelInfo);
3032  }
3033 
3034  /*
3035  * Switch to per-tuple context before calling NextCopyFrom, which does
3036  * evaluate default expressions etc. and requires per-tuple context.
3037  */
3039 
3040  ExecClearTuple(myslot);
3041 
3042  /* Directly store the values/nulls array in the slot */
3043  if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
3044  break;
3045 
3046  ExecStoreVirtualTuple(myslot);
3047 
3048  /*
3049  * Constraints and where clause might reference the tableoid column,
3050  * so (re-)initialize tts_tableOid before evaluating them.
3051  */
3052  myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
3053 
3054  /* Triggers and stuff need to be invoked in query context. */
3055  MemoryContextSwitchTo(oldcontext);
3056 
3057  if (cstate->whereClause)
3058  {
3059  econtext->ecxt_scantuple = myslot;
3060  /* Skip items that don't match COPY's WHERE clause */
3061  if (!ExecQual(cstate->qualexpr, econtext))
3062  continue;
3063  }
3064 
3065  /* Determine the partition to insert the tuple into */
3066  if (proute)
3067  {
3068  TupleConversionMap *map;
3069 
3070  /*
3071  * Attempt to find a partition suitable for this tuple.
3072  * ExecFindPartition() will raise an error if none can be found or
3073  * if the found partition is not suitable for INSERTs.
3074  */
3075  resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
3076  proute, myslot, estate);
3077 
3078  if (prevResultRelInfo != resultRelInfo)
3079  {
3080  /* Determine which triggers exist on this partition */
3081  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
3082  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
3083 
3084  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
3085  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
3086 
3087  /*
3088  * Disable multi-inserts when the partition has BEFORE/INSTEAD
3089  * OF triggers, or if the partition is a foreign partition.
3090  */
3091  leafpart_use_multi_insert = insertMethod == CIM_MULTI_CONDITIONAL &&
3092  !has_before_insert_row_trig &&
3093  !has_instead_insert_row_trig &&
3094  resultRelInfo->ri_FdwRoutine == NULL;
3095 
3096  /* Set the multi-insert buffer to use for this partition. */
3097  if (leafpart_use_multi_insert)
3098  {
3099  if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL)
3100  CopyMultiInsertInfoSetupBuffer(&multiInsertInfo,
3101  resultRelInfo);
3102  }
3103  else if (insertMethod == CIM_MULTI_CONDITIONAL &&
3104  !CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
3105  {
3106  /*
3107  * Flush pending inserts if this partition can't use
3108  * batching, so rows are visible to triggers etc.
3109  */
3110  CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo);
3111  }
3112 
3113  if (bistate != NULL)
3114  ReleaseBulkInsertStatePin(bistate);
3115  prevResultRelInfo = resultRelInfo;
3116  }
3117 
3118  /*
3119  * For ExecInsertIndexTuples() to work on the partition's indexes
3120  */
3121  estate->es_result_relation_info = resultRelInfo;
3122 
3123  /*
3124  * If we're capturing transition tuples, we might need to convert
3125  * from the partition rowtype to root rowtype.
3126  */
3127  if (cstate->transition_capture != NULL)
3128  {
3129  if (has_before_insert_row_trig)
3130  {
3131  /*
3132  * If there are any BEFORE triggers on the partition,
3133  * we'll have to be ready to convert their result back to
3134  * tuplestore format.
3135  */
3137  cstate->transition_capture->tcs_map =
3138  resultRelInfo->ri_PartitionInfo->pi_PartitionToRootMap;
3139  }
3140  else
3141  {
3142  /*
3143  * Otherwise, just remember the original unconverted
3144  * tuple, to avoid a needless round trip conversion.
3145  */
3147  cstate->transition_capture->tcs_map = NULL;
3148  }
3149  }
3150 
3151  /*
3152  * We might need to convert from the root rowtype to the partition
3153  * rowtype.
3154  */
3155  map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap;
3156  if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert)
3157  {
3158  /* non batch insert */
3159  if (map != NULL)
3160  {
3161  TupleTableSlot *new_slot;
3162 
3163  new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot;
3164  myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
3165  }
3166  }
3167  else
3168  {
3169  /*
3170  * Prepare to queue up tuple for later batch insert into
3171  * current partition.
3172  */
3173  TupleTableSlot *batchslot;
3174 
3175  /* no other path available for partitioned table */
3176  Assert(insertMethod == CIM_MULTI_CONDITIONAL);
3177 
3178  batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
3179  resultRelInfo);
3180 
3181  if (map != NULL)
3182  myslot = execute_attr_map_slot(map->attrMap, myslot,
3183  batchslot);
3184  else
3185  {
3186  /*
3187  * This looks more expensive than it is (Believe me, I
3188  * optimized it away. Twice.). The input is in virtual
3189  * form, and we'll materialize the slot below - for most
3190  * slot types the copy performs the work materialization
3191  * would later require anyway.
3192  */
3193  ExecCopySlot(batchslot, myslot);
3194  myslot = batchslot;
3195  }
3196  }
3197 
3198  /* ensure that triggers etc see the right relation */
3199  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
3200  }
3201 
3202  skip_tuple = false;
3203 
3204  /* BEFORE ROW INSERT Triggers */
3205  if (has_before_insert_row_trig)
3206  {
3207  if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot))
3208  skip_tuple = true; /* "do nothing" */
3209  }
3210 
3211  if (!skip_tuple)
3212  {
3213  /*
3214  * If there is an INSTEAD OF INSERT ROW trigger, let it handle the
3215  * tuple. Otherwise, proceed with inserting the tuple into the
3216  * table or foreign table.
3217  */
3218  if (has_instead_insert_row_trig)
3219  {
3220  ExecIRInsertTriggers(estate, resultRelInfo, myslot);
3221  }
3222  else
3223  {
3224  /* Compute stored generated columns */
3225  if (resultRelInfo->ri_RelationDesc->rd_att->constr &&
3227  ExecComputeStoredGenerated(estate, myslot);
3228 
3229  /*
3230  * If the target is a plain table, check the constraints of
3231  * the tuple.
3232  */
3233  if (resultRelInfo->ri_FdwRoutine == NULL &&
3234  resultRelInfo->ri_RelationDesc->rd_att->constr)
3235  ExecConstraints(resultRelInfo, myslot, estate);
3236 
3237  /*
3238  * Also check the tuple against the partition constraint, if
3239  * there is one; except that if we got here via tuple-routing,
3240  * we don't need to if there's no BR trigger defined on the
3241  * partition.
3242  */
3243  if (resultRelInfo->ri_PartitionCheck &&
3244  (proute == NULL || has_before_insert_row_trig))
3245  ExecPartitionCheck(resultRelInfo, myslot, estate, true);
3246 
3247  /* Store the slot in the multi-insert buffer, when enabled. */
3248  if (insertMethod == CIM_MULTI || leafpart_use_multi_insert)
3249  {
3250  /*
3251  * The slot previously might point into the per-tuple
3252  * context. For batching it needs to be longer lived.
3253  */
3254  ExecMaterializeSlot(myslot);
3255 
3256  /* Add this tuple to the tuple buffer */
3257  CopyMultiInsertInfoStore(&multiInsertInfo,
3258  resultRelInfo, myslot,
3259  cstate->line_buf.len,
3260  cstate->cur_lineno);
3261 
3262  /*
3263  * If enough inserts have queued up, then flush all
3264  * buffers out to their tables.
3265  */
3266  if (CopyMultiInsertInfoIsFull(&multiInsertInfo))
3267  CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo);
3268  }
3269  else
3270  {
3271  List *recheckIndexes = NIL;
3272 
3273  /* OK, store the tuple */
3274  if (resultRelInfo->ri_FdwRoutine != NULL)
3275  {
3276  myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
3277  resultRelInfo,
3278  myslot,
3279  NULL);
3280 
3281  if (myslot == NULL) /* "do nothing" */
3282  continue; /* next tuple please */
3283 
3284  /*
3285  * AFTER ROW Triggers might reference the tableoid
3286  * column, so (re-)initialize tts_tableOid before
3287  * evaluating them.
3288  */
3289  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
3290  }
3291  else
3292  {
3293  /* OK, store the tuple and create index entries for it */
3294  table_tuple_insert(resultRelInfo->ri_RelationDesc,
3295  myslot, mycid, ti_options, bistate);
3296 
3297  if (resultRelInfo->ri_NumIndices > 0)
3298  recheckIndexes = ExecInsertIndexTuples(myslot,
3299  estate,
3300  false,
3301  NULL,
3302  NIL);
3303  }
3304 
3305  /* AFTER ROW INSERT Triggers */
3306  ExecARInsertTriggers(estate, resultRelInfo, myslot,
3307  recheckIndexes, cstate->transition_capture);
3308 
3309  list_free(recheckIndexes);
3310  }
3311  }
3312 
3313  /*
3314  * We count only tuples not suppressed by a BEFORE INSERT trigger
3315  * or FDW; this is the same definition used by nodeModifyTable.c
3316  * for counting tuples inserted by an INSERT command.
3317  */
3318  processed++;
3319  }
3320  }
3321 
3322  /* Flush any remaining buffered tuples */
3323  if (insertMethod != CIM_SINGLE)
3324  {
3325  if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
3326  CopyMultiInsertInfoFlush(&multiInsertInfo, NULL);
3327  }
3328 
3329  /* Done, clean up */
3330  error_context_stack = errcallback.previous;
3331 
3332  if (bistate != NULL)
3333  FreeBulkInsertState(bistate);
3334 
3335  MemoryContextSwitchTo(oldcontext);
3336 
3337  /*
3338  * In the old protocol, tell pqcomm that we can process normal protocol
3339  * messages again.
3340  */
3341  if (cstate->copy_dest == COPY_OLD_FE)
3342  pq_endmsgread();
3343 
3344  /* Execute AFTER STATEMENT insertion triggers */
3345  ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture);
3346 
3347  /* Handle queued AFTER triggers */
3348  AfterTriggerEndQuery(estate);
3349 
3350  ExecResetTupleTable(estate->es_tupleTable, false);
3351 
3352  /* Allow the FDW to shut down */
3353  if (target_resultRelInfo->ri_FdwRoutine != NULL &&
3354  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
3355  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate,
3356  target_resultRelInfo);
3357 
3358  /* Tear down the multi-insert buffer data */
3359  if (insertMethod != CIM_SINGLE)
3360  CopyMultiInsertInfoCleanup(&multiInsertInfo);
3361 
3362  ExecCloseIndices(target_resultRelInfo);
3363 
3364  /* Close all the partitioned tables, leaf partitions, and their indices */
3365  if (proute)
3366  ExecCleanupTupleRouting(mtstate, proute);
3367 
3368  /* Close any trigger target relations */
3369  ExecCleanUpTriggerState(estate);
3370 
3371  FreeExecutorState(estate);
3372 
3373  return processed;
3374 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:77
AttrNumber * attrMap
Definition: tupconvert.h:26
int ri_NumIndices
Definition: execnodes.h:414
Node * whereClause
Definition: copy.c:156
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:476
#define NIL
Definition: pg_list.h:65
Oid tts_tableOid
Definition: tuptable.h:131
uint32 CommandId
Definition: c.h:521
void ExecInitRangeTable(EState *estate, List *rangeTable)
Definition: execUtils.c:724
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1277
Relation ri_RelationDesc
Definition: execnodes.h:411
List * range_table
Definition: copy.c:184
static void CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, TupleTableSlot *slot, int tuplen, uint64 lineno)
Definition: copy.c:2635
int errhint(const char *fmt,...)
Definition: elog.c:974
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
Definition: trigger.c:2602
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition: execnodes.h:488
void CopyFromErrorCallback(void *arg)
Definition: copy.c:2239
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
#define ResetPerTupleExprContext(estate)
Definition: executor.h:510
#define TABLE_INSERT_FROZEN
Definition: tableam.h:132
#define castNode(_type_, nodeptr)
Definition: nodes.h:594
BeginForeignInsert_function BeginForeignInsert
Definition: fdwapi.h:215
ResultRelInfo * resultRelInfo
Definition: execnodes.h:1169
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:211
struct PartitionRoutingInfo * ri_PartitionInfo
Definition: execnodes.h:485
#define XLogIsNeeded()
Definition: xlog.h:181
static void CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copy.c:2366
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1905
StringInfoData line_buf
Definition: copy.c:211
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition: snapmgr.c:1689
int errcode(int sqlerrcode)
Definition: elog.c:570
TupleTableSlot * execute_attr_map_slot(AttrNumber *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:425
CmdType operation
Definition: execnodes.h:1161
SubTransactionId rd_newRelfilenodeSubid
Definition: rel.h:80
Datum * tts_values
Definition: tuptable.h:126
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:724
EState * state
Definition: execnodes.h:942
Form_pg_class rd_rel
Definition: rel.h:83
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:365
bool volatile_defexprs
Definition: copy.c:183
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
static void CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, CopyState cstate, EState *estate, CommandId mycid, int ti_options)
Definition: copy.c:2386
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:1123
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:207
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:151
void ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot)
CopyDest copy_dest
Definition: copy.c:117
ErrorContextCallback * error_context_stack
Definition: elog.c:88
uint64 cur_lineno
Definition: copy.c:160
bool trig_insert_instead_row
Definition: reltrigger.h:57
void FreeExecutorState(EState *estate)
Definition: execUtils.c:190
Relation rel
Definition: copy.c:130
#define GetPerTupleExprContext(estate)
Definition: executor.h:501
BulkInsertState GetBulkInsertState(void)
Definition: heapam.c:1815
bool trig_insert_new_table
Definition: reltrigger.h:74
bool has_generated_stored
Definition: tupdesc.h:45
TupleConversionMap * pi_RootToPartitionMap
Definition: execPartition.h:37
bool ThereAreNoReadyPortals(void)
Definition: portalmem.c:1208
#define ERROR
Definition: elog.h:43
PlanState ps
Definition: execnodes.h:1160
void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute)
bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition: trigger.c:2535
static bool CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2411
TupleConversionMap * tcs_map
Definition: trigger.h:73
static bool CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2423
List * ExecInsertIndexTuples(TupleTableSlot *slot, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes)
Definition: execIndexing.c:273
TriggerDesc * trigdesc
Definition: rel.h:89
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
Definition: execMain.c:1076
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
Definition: trigger.c:2467
struct TransitionCaptureState * mt_transition_capture
Definition: execnodes.h:1187
bool * tts_isnull
Definition: tuptable.h:128
static void CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri)
Definition: copy.c:2554
TupleConstr * constr
Definition: tupdesc.h:85
ResultRelInfo * es_result_relations
Definition: execnodes.h:520
#define RelationGetRelationName(relation)
Definition: rel.h:453
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:440
#define TABLE_INSERT_SKIP_WAL
Definition: tableam.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, Relation rel)
#define ereport(elevel, rest)
Definition: elog.h:141
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:512
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:423
EState * CreateExecutorState(void)
Definition: execUtils.c:88
SubTransactionId rd_createSubid
Definition: rel.h:79
Definition: copy.c:94
bool trig_insert_before_row
Definition: reltrigger.h:55
List * es_tupleTable
Definition: execnodes.h:552
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1156
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
Definition: trigger.c:2524
TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
Definition: trigger.c:4663
int es_num_result_relations
Definition: execnodes.h:521
#define TABLE_INSERT_SKIP_FSM
Definition: tableam.h:131
TupleConversionMap * pi_PartitionToRootMap
Definition: execPartition.h:43
List * ri_PartitionCheck
Definition: execnodes.h:476
TupleDesc rd_att
Definition: rel.h:84
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:444
bool freeze
Definition: copy.c:137
Plan * plan
Definition: execnodes.h:940
void pq_endmsgread(void)
Definition: pqcomm.c:1235
void AfterTriggerBeginQuery(void)
Definition: trigger.c:4785
#define makeNode(_type_)
Definition: nodes.h:573
#define Assert(condition)
Definition: c.h:732
void FreeBulkInsertState(BulkInsertState bistate)
Definition: heapam.c:1829
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition: trigger.c:2617
CopyInsertMethod
Definition: copy.c:91
bool NextCopyFrom(CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls)
Definition: copy.c:3688
static TupleTableSlot * CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copy.c:2616
static void CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2600
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:224
#define InvalidSubTransactionId
Definition: c.h:513
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
Definition: heapam.c:1841
#define GetPerTupleMemoryContext(estate)
Definition: executor.h:506
void ExecCleanUpTriggerState(EState *estate)
Definition: execMain.c:1454
void AfterTriggerEndQuery(EState *estate)
Definition: trigger.c:4805
int errmsg(const char *fmt,...)
Definition: elog.c:784
void list_free(List *list)
Definition: list.c:1377
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition: execMain.c:1792
TransitionCaptureState * transition_capture
Definition: copy.c:187
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:746
ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:419
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:226
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1517
EndForeignInsert_function EndForeignInsert
Definition: fdwapi.h:216
TupleTableSlot * pi_PartitionTupleSlot
Definition: execPartition.h:49
TupleTableSlot * tcs_original_insert_tuple
Definition: trigger.h:82
ExprState * qualexpr
Definition: copy.c:185
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:522

◆ CopyFromErrorCallback()

void CopyFromErrorCallback ( void *  arg)

Definition at line 2239 of file copy.c.

References CopyStateData::binary, CopyStateData::cur_attname, CopyStateData::cur_attval, CopyStateData::cur_lineno, CopyStateData::cur_relname, StringInfoData::data, errcontext, limit_printout_length(), CopyStateData::line_buf, CopyStateData::line_buf_converted, CopyStateData::line_buf_valid, CopyStateData::need_transcoding, pfree(), snprintf, and UINT64_FORMAT.

Referenced by CopyFrom(), file_acquire_sample_rows(), and fileIterateForeignScan().

2240 {
2241  CopyState cstate = (CopyState) arg;
2242  char curlineno_str[32];
2243 
2244  snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
2245  cstate->cur_lineno);
2246 
2247  if (cstate->binary)
2248  {
2249  /* can't usefully display the data */
2250  if (cstate->cur_attname)
2251  errcontext("COPY %s, line %s, column %s",
2252  cstate->cur_relname, curlineno_str,
2253  cstate->cur_attname);
2254  else
2255  errcontext("COPY %s, line %s",
2256  cstate->cur_relname, curlineno_str);
2257  }
2258  else
2259  {
2260  if (cstate->cur_attname && cstate->cur_attval)
2261  {
2262  /* error is relevant to a particular column */
2263  char *attval;
2264 
2265  attval = limit_printout_length(cstate->cur_attval);
2266  errcontext("COPY %s, line %s, column %s: \"%s\"",
2267  cstate->cur_relname, curlineno_str,
2268  cstate->cur_attname, attval);
2269  pfree(attval);
2270  }
2271  else if (cstate->cur_attname)
2272  {
2273  /* error is relevant to a particular column, value is NULL */
2274  errcontext("COPY %s, line %s, column %s: null input",
2275  cstate->cur_relname, curlineno_str,
2276  cstate->cur_attname);
2277  }
2278  else
2279  {
2280  /*
2281  * Error is relevant to a particular line.
2282  *
2283  * If line_buf still contains the correct line, and it's already
2284  * transcoded, print it. If it's still in a foreign encoding, it's
2285  * quite likely that the error is precisely a failure to do
2286  * encoding conversion (ie, bad data). We dare not try to convert
2287  * it, and at present there's no way to regurgitate it without
2288  * conversion. So we have to punt and just report the line number.
2289  */
2290  if (cstate->line_buf_valid &&
2291  (cstate->line_buf_converted || !cstate->need_transcoding))
2292  {
2293  char *lineval;
2294 
2295  lineval = limit_printout_length(cstate->line_buf.data);
2296  errcontext("COPY %s, line %s: \"%s\"",
2297  cstate->cur_relname, curlineno_str, lineval);
2298  pfree(lineval);
2299  }
2300  else
2301  {
2302  errcontext("COPY %s, line %s",
2303  cstate->cur_relname, curlineno_str);
2304  }
2305  }
2306  }
2307 }
bool binary
Definition: copy.c:136
bool need_transcoding
Definition: copy.c:126
StringInfoData line_buf
Definition: copy.c:211
bool line_buf_valid
Definition: copy.c:213
bool line_buf_converted
Definition: copy.c:212
uint64 cur_lineno
Definition: copy.c:160
const char * cur_attname
Definition: copy.c:161
void pfree(void *pointer)
Definition: mcxt.c:1056
static char * limit_printout_length(const char *str)
Definition: copy.c:2319
const char * cur_relname
Definition: copy.c:159
#define errcontext
Definition: elog.h:183
struct CopyStateData * CopyState
Definition: copy.h:23
void * arg
const char * cur_attval
Definition: copy.c:162
#define snprintf
Definition: port.h:192
#define UINT64_FORMAT
Definition: c.h:401

◆ CreateCopyDestReceiver()

DestReceiver* CreateCopyDestReceiver ( void  )

Definition at line 5202 of file copy.c.

References copy_dest_destroy(), copy_dest_receive(), copy_dest_shutdown(), copy_dest_startup(), DestCopyOut, and palloc().

Referenced by CreateDestReceiver().

5203 {
5204  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
5205 
5206  self->pub.receiveSlot = copy_dest_receive;
5207  self->pub.rStartup = copy_dest_startup;
5208  self->pub.rShutdown = copy_dest_shutdown;
5209  self->pub.rDestroy = copy_dest_destroy;
5210  self->pub.mydest = DestCopyOut;
5211 
5212  self->cstate = NULL; /* will be set later */
5213  self->processed = 0;
5214 
5215  return (DestReceiver *) self;
5216 }
Definition: copy.c:229
static void copy_dest_destroy(DestReceiver *self)
Definition: copy.c:5193
static void copy_dest_shutdown(DestReceiver *self)
Definition: copy.c:5184
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copy.c:5159
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copy.c:5168
void * palloc(Size size)
Definition: mcxt.c:949

◆ DoCopy()

void DoCopy ( ParseState state,
const CopyStmt stmt,
int  stmt_location,
int  stmt_len,
uint64 *  processed 
)

Definition at line 838 of file copy.c.

References AccessShareLock, ACL_INSERT, ACL_SELECT, addRangeTableEntryForRelation(), addRTEtoQuery(), Assert, assign_expr_collations(), CopyStmt::attlist, BeginCopyFrom(), BeginCopyTo(), bms_add_member(), canonicalize_qual(), check_enable_rls(), coerce_to_boolean(), CopyFrom(), CopyGetAttnums(), cur, DoCopyTo(), EndCopyFrom(), EndCopyTo(), ereport, errcode(), errhint(), errmsg(), ERROR, eval_const_expressions(), ExecCheckRTPerms(), EXPR_KIND_COPY_WHERE, ColumnRef::fields, CopyStmt::filename, FirstLowInvalidHeapAttributeNumber, SelectStmt::fromClause, get_namespace_name(), GetUserId(), ResTarget::indirection, RangeTblEntry::insertedCols, InvalidOid, CopyStmt::is_from, is_member_of_role(), CopyStmt::is_program, lappend(), lfirst, lfirst_int, list_make1, ColumnRef::location, ResTarget::location, make_ands_implicit(), makeNode, makeRangeVar(), ResTarget::name, NIL, NoLock, CopyStmt::options, ParseState::p_rtable, PreventCommandIfParallelMode(), PreventCommandIfReadOnly(), pstrdup(), CopyStmt::query, RelationData::rd_islocaltemp, CopyStateData::rel, CopyStmt::relation, RelationGetDescr, RelationGetNamespace, RelationGetRelationName, RelationGetRelid, RangeTblEntry::relid, RangeTblEntry::requiredPerms, RLS_ENABLED, RowExclusiveLock, select, RangeTblEntry::selectedCols, RawStmt::stmt, RawStmt::stmt_len, RawStmt::stmt_location, table_close(), table_openrv(), SelectStmt::targetList, transformExpr(), ResTarget::val, CopyStateData::whereClause, CopyStmt::whereClause, and XactReadOnly.

Referenced by standard_ProcessUtility().

841 {
842  CopyState cstate;
843  bool is_from = stmt->is_from;
844  bool pipe = (stmt->filename == NULL);
845  Relation rel;
846  Oid relid;
847  RawStmt *query = NULL;
848  Node *whereClause = NULL;
849 
850  /*
851  * Disallow COPY to/from file or program except to users with the
852  * appropriate role.
853  */
854  if (!pipe)
855  {
856  if (stmt->is_program)
857  {
858  if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_EXECUTE_SERVER_PROGRAM))
859  ereport(ERROR,
860  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
861  errmsg("must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program"),
862  errhint("Anyone can COPY to stdout or from stdin. "
863  "psql's \\copy command also works for anyone.")));
864  }
865  else
866  {
867  if (is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES))
868  ereport(ERROR,
869  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
870  errmsg("must be superuser or a member of the pg_read_server_files role to COPY from a file"),
871  errhint("Anyone can COPY to stdout or from stdin. "
872  "psql's \\copy command also works for anyone.")));
873 
874  if (!is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_WRITE_SERVER_FILES))
875  ereport(ERROR,
876  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
877  errmsg("must be superuser or a member of the pg_write_server_files role to COPY to a file"),
878  errhint("Anyone can COPY to stdout or from stdin. "
879  "psql's \\copy command also works for anyone.")));
880  }
881  }
882 
883  if (stmt->relation)
884  {
885  LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
886  RangeTblEntry *rte;
887  TupleDesc tupDesc;
888  List *attnums;
889  ListCell *cur;
890 
891  Assert(!stmt->query);
892 
893  /* Open and lock the relation, using the appropriate lock type. */
894  rel = table_openrv(stmt->relation, lockmode);
895 
896  relid = RelationGetRelid(rel);
897 
898  rte = addRangeTableEntryForRelation(pstate, rel, lockmode,
899  NULL, false, false);
900  rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
901 
902  if (stmt->whereClause)
903  {
904  /* add rte to column namespace */
905  addRTEtoQuery(pstate, rte, false, true, true);
906 
907  /* Transform the raw expression tree */
908  whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
909 
910  /* Make sure it yields a boolean result. */
911  whereClause = coerce_to_boolean(pstate, whereClause, "WHERE");
912 
913  /* we have to fix its collations too */
914  assign_expr_collations(pstate, whereClause);
915 
916  whereClause = eval_const_expressions(NULL, whereClause);
917 
918  whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
919  whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
920  }
921 
922  tupDesc = RelationGetDescr(rel);
923  attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
924  foreach(cur, attnums)
925  {
926  int attno = lfirst_int(cur) -
928 
929  if (is_from)
930  rte->insertedCols = bms_add_member(rte->insertedCols, attno);
931  else
932  rte->selectedCols = bms_add_member(rte->selectedCols, attno);
933  }
934  ExecCheckRTPerms(pstate->p_rtable, true);
935 
936  /*
937  * Permission check for row security policies.
938  *
939  * check_enable_rls will ereport(ERROR) if the user has requested
940  * something invalid and will otherwise indicate if we should enable
941  * RLS (returns RLS_ENABLED) or not for this COPY statement.
942  *
943  * If the relation has a row security policy and we are to apply it
944  * then perform a "query" copy and allow the normal query processing
945  * to handle the policies.
946  *
947  * If RLS is not enabled for this, then just fall through to the
948  * normal non-filtering relation handling.
949  */
950  if (check_enable_rls(rte->relid, InvalidOid, false) == RLS_ENABLED)
951  {
953  ColumnRef *cr;
954  ResTarget *target;
955  RangeVar *from;
956  List *targetList = NIL;
957 
958  if (is_from)
959  ereport(ERROR,
960  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
961  errmsg("COPY FROM not supported with row-level security"),
962  errhint("Use INSERT statements instead.")));
963 
964  /*
965  * Build target list
966  *
967  * If no columns are specified in the attribute list of the COPY
968  * command, then the target list is 'all' columns. Therefore, '*'
969  * should be used as the target list for the resulting SELECT
970  * statement.
971  *
972  * In the case that columns are specified in the attribute list,
973  * create a ColumnRef and ResTarget for each column and add them
974  * to the target list for the resulting SELECT statement.
975  */
976  if (!stmt->attlist)
977  {
978  cr = makeNode(ColumnRef);
980  cr->location = -1;
981 
982  target = makeNode(ResTarget);
983  target->name = NULL;
984  target->indirection = NIL;
985  target->val = (Node *) cr;
986  target->location = -1;
987 
988  targetList = list_make1(target);
989  }
990  else
991  {
992  ListCell *lc;
993 
994  foreach(lc, stmt->attlist)
995  {
996  /*
997  * Build the ColumnRef for each column. The ColumnRef
998  * 'fields' property is a String 'Value' node (see
999  * nodes/value.h) that corresponds to the column name
1000  * respectively.
1001  */
1002  cr = makeNode(ColumnRef);
1003  cr->fields = list_make1(lfirst(lc));
1004  cr->location = -1;
1005 
1006  /* Build the ResTarget and add the ColumnRef to it. */
1007  target = makeNode(ResTarget);
1008  target->name = NULL;
1009  target->indirection = NIL;
1010  target->val = (Node *) cr;
1011  target->location = -1;
1012 
1013  /* Add each column to the SELECT statement's target list */
1014  targetList = lappend(targetList, target);
1015  }
1016  }
1017 
1018  /*
1019  * Build RangeVar for from clause, fully qualified based on the
1020  * relation which we have opened and locked.
1021  */
1024  -1);
1025 
1026  /* Build query */
1027  select = makeNode(SelectStmt);
1028  select->targetList = targetList;
1029  select->fromClause = list_make1(from);
1030 
1031  query = makeNode(RawStmt);
1032  query->stmt = (Node *) select;
1033  query->stmt_location = stmt_location;
1034  query->stmt_len = stmt_len;
1035 
1036  /*
1037  * Close the relation for now, but keep the lock on it to prevent
1038  * changes between now and when we start the query-based COPY.
1039  *
1040  * We'll reopen it later as part of the query-based COPY.
1041  */
1042  table_close(rel, NoLock);
1043  rel = NULL;
1044  }
1045  }
1046  else
1047  {
1048  Assert(stmt->query);
1049 
1050  query = makeNode(RawStmt);
1051  query->stmt = stmt->query;
1052  query->stmt_location = stmt_location;
1053  query->stmt_len = stmt_len;
1054 
1055  relid = InvalidOid;
1056  rel = NULL;
1057  }
1058 
1059  if (is_from)
1060  {
1061  Assert(rel);
1062 
1063  /* check read-only transaction and parallel mode */
1064  if (XactReadOnly && !rel->rd_islocaltemp)
1065  PreventCommandIfReadOnly("COPY FROM");
1066  PreventCommandIfParallelMode("COPY FROM");
1067 
1068  cstate = BeginCopyFrom(pstate, rel, stmt->filename, stmt->is_program,
1069  NULL, stmt->attlist, stmt->options);
1070  cstate->whereClause = whereClause;
1071  *processed = CopyFrom(cstate); /* copy from file to database */
1072  EndCopyFrom(cstate);
1073  }
1074  else
1075  {
1076  cstate = BeginCopyTo(pstate, rel, query, relid,
1077  stmt->filename, stmt->is_program,
1078  stmt->attlist, stmt->options);
1079  *processed = DoCopyTo(cstate); /* copy from database to file */
1080  EndCopyTo(cstate);
1081  }
1082 
1083  /*
1084  * Close the relation. If reading, we can release the AccessShareLock we
1085  * got; if writing, we should hold the lock until end of transaction to
1086  * ensure that updates will be committed before lock is released.
1087  */
1088  if (rel != NULL)
1089  table_close(rel, (is_from ? NoLock : AccessShareLock));
1090 }
List * indirection
Definition: parsenodes.h:441
Node * whereClause
Definition: copy.c:156
#define NIL
Definition: pg_list.h:65
Node * whereClause
Definition: parsenodes.h:1996
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Node * val
Definition: parsenodes.h:442
int errhint(const char *fmt,...)
Definition: elog.c:974
void PreventCommandIfParallelMode(const char *cmdname)
Definition: utility.c:257
List * attlist
Definition: parsenodes.h:1990
List * fromClause
Definition: parsenodes.h:1575
#define RelationGetDescr(relation)
Definition: rel.h:445
int LOCKMODE
Definition: lockdefs.h:26
char * name
Definition: parsenodes.h:440
Oid GetUserId(void)
Definition: miscinit.c:380
CopyState BeginCopyFrom(ParseState *pstate, Relation rel, const char *filename, bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options)
Definition: copy.c:3387
char * pstrdup(const char *in)
Definition: mcxt.c:1186
bool rd_islocaltemp
Definition: rel.h:59
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:145
#define AccessShareLock
Definition: lockdefs.h:36
Definition: nodes.h:525
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:570
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2253
uint64 CopyFrom(CopyState cstate)
Definition: copy.c:2658
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
AclMode requiredPerms
Definition: parsenodes.h:1096
unsigned int Oid
Definition: postgres_ext.h:31
bool is_program
Definition: parsenodes.h:1993
int location
Definition: parsenodes.h:236
int location
Definition: parsenodes.h:443
#define list_make1(x1)
Definition: pg_list.h:227
void assign_expr_collations(ParseState *pstate, Node *expr)
Bitmapset * selectedCols
Definition: parsenodes.h:1098
static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, Oid queryRelId, const char *filename, bool is_program, List *attnamelist, List *options)
Definition: copy.c:1825
#define ERROR
Definition: elog.h:43
#define lfirst_int(lc)
Definition: pg_list.h:191
RangeVar * relation
Definition: parsenodes.h:1987
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
Node * stmt
Definition: parsenodes.h:1485
#define NoLock
Definition: lockdefs.h:34
List * targetList
Definition: parsenodes.h:1574
static uint64 DoCopyTo(CopyState cstate)
Definition: copy.c:1963
#define RowExclusiveLock
Definition: lockdefs.h:38
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:292
List * options
Definition: parsenodes.h:1995
#define select(n, r, w, e, timeout)
Definition: win32_port.h:436
#define RelationGetRelationName(relation)
Definition: rel.h:453
#define ereport(elevel, rest)
Definition: elog.h:141
void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
List * lappend(List *list, void *datum)
Definition: list.c:322
static List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:5078
#define ACL_SELECT
Definition: parsenodes.h:75
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:716
int stmt_len
Definition: parsenodes.h:1487
int stmt_location
Definition: parsenodes.h:1486
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: table.c:68
#define InvalidOid
Definition: postgres_ext.h:36
bool XactReadOnly
Definition: xact.c:78
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4932
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition: rls.c:52
void EndCopyFrom(CopyState cstate)
Definition: copy.c:3876
#define makeNode(_type_)
Definition: nodes.h:573
#define Assert(condition)
Definition: c.h:732
#define lfirst(lc)
Definition: pg_list.h:190
#define ACL_INSERT
Definition: parsenodes.h:74
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
void PreventCommandIfReadOnly(const char *cmdname)
Definition: utility.c:239
Node * query
Definition: parsenodes.h:1988
bool is_from
Definition: parsenodes.h:1992
int errmsg(const char *fmt,...)
Definition: elog.c:784
Bitmapset * insertedCols
Definition: parsenodes.h:1099
bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation)
Definition: execMain.c:571
char * filename
Definition: parsenodes.h:1994
static void EndCopyTo(CopyState cstate)
Definition: copy.c:1998
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:419
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420
List * fields
Definition: parsenodes.h:235
#define RelationGetNamespace(relation)
Definition: rel.h:460
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)

◆ EndCopyFrom()

void EndCopyFrom ( CopyState  cstate)

Definition at line 3876 of file copy.c.

References EndCopy().

Referenced by DoCopy(), file_acquire_sample_rows(), fileEndForeignScan(), and fileReScanForeignScan().

3877 {
3878  /* No COPY FROM related resources except memory. */
3879 
3880  EndCopy(cstate);
3881 }
static void EndCopy(CopyState cstate)
Definition: copy.c:1802

◆ NextCopyFrom()

bool NextCopyFrom ( CopyState  cstate,
ExprContext econtext,
Datum values,
bool nulls 
)

Definition at line 3688 of file copy.c.

References Assert, attnum, CopyStateData::attnumlist, CopyStateData::binary, CopyStateData::convert_select_flags, CopyStateData::copy_dest, COPY_OLD_FE, CopyGetData(), CopyGetInt16(), CopyReadBinaryAttribute(), CopyStateData::csv_mode, cur, CopyStateData::cur_attname, CopyStateData::cur_attval, CopyStateData::cur_lineno, CurrentMemoryContext, CopyStateData::defexprs, CopyStateData::defmap, ExprContext::ecxt_per_tuple_memory, ereport, errcode(), errmsg(), ERROR, ExecEvalExpr(), CopyStateData::force_notnull_flags, CopyStateData::force_null_flags, i, CopyStateData::in_functions, InputFunctionCall(), lfirst_int, list_length(), MemSet, NameStr, TupleDescData::natts, NextCopyFromRawFields(), CopyStateData::null_print, CopyStateData::num_defaults, CopyStateData::rel, RelationGetDescr, TupleDescAttr, and CopyStateData::typioparams.

Referenced by CopyFrom(), file_acquire_sample_rows(), and fileIterateForeignScan().

3690 {
3691  TupleDesc tupDesc;
3692  AttrNumber num_phys_attrs,
3693  attr_count,
3694  num_defaults = cstate->num_defaults;
3695  FmgrInfo *in_functions = cstate->in_functions;
3696  Oid *typioparams = cstate->typioparams;
3697  int i;
3698  int *defmap = cstate->defmap;
3699  ExprState **defexprs = cstate->defexprs;
3700 
3701  tupDesc = RelationGetDescr(cstate->rel);
3702  num_phys_attrs = tupDesc->natts;
3703  attr_count = list_length(cstate->attnumlist);
3704 
3705  /* Initialize all values for row to NULL */
3706  MemSet(values, 0, num_phys_attrs * sizeof(Datum));
3707  MemSet(nulls, true, num_phys_attrs * sizeof(bool));
3708 
3709  if (!cstate->binary)
3710  {
3711  char **field_strings;
3712  ListCell *cur;
3713  int fldct;
3714  int fieldno;
3715  char *string;
3716 
3717  /* read raw fields in the next line */
3718  if (!NextCopyFromRawFields(cstate, &field_strings, &fldct))
3719  return false;
3720 
3721  /* check for overflowing fields */
3722  if (attr_count > 0 && fldct > attr_count)
3723  ereport(ERROR,
3724  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3725  errmsg("extra data after last expected column")));
3726 
3727  fieldno = 0;
3728 
3729  /* Loop to read the user attributes on the line. */
3730  foreach(cur, cstate->attnumlist)
3731  {
3732  int attnum = lfirst_int(cur);
3733  int m = attnum - 1;
3734  Form_pg_attribute att = TupleDescAttr(tupDesc, m);
3735 
3736  if (fieldno >= fldct)
3737  ereport(ERROR,
3738  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3739  errmsg("missing data for column \"%s\"",
3740  NameStr(att->attname))));
3741  string = field_strings[fieldno++];
3742 
3743  if (cstate->convert_select_flags &&
3744  !cstate->convert_select_flags[m])
3745  {
3746  /* ignore input field, leaving column as NULL */
3747  continue;
3748  }
3749 
3750  if (cstate->csv_mode)
3751  {
3752  if (string == NULL &&
3753  cstate->force_notnull_flags[m])
3754  {
3755  /*
3756  * FORCE_NOT_NULL option is set and column is NULL -
3757  * convert it to the NULL string.
3758  */
3759  string = cstate->null_print;
3760  }
3761  else if (string != NULL && cstate->force_null_flags[m]
3762  && strcmp(string, cstate->null_print) == 0)
3763  {
3764  /*
3765  * FORCE_NULL option is set and column matches the NULL
3766  * string. It must have been quoted, or otherwise the
3767  * string would already have been set to NULL. Convert it
3768  * to NULL as specified.
3769  */
3770  string = NULL;
3771  }
3772  }
3773 
3774  cstate->cur_attname = NameStr(att->attname);
3775  cstate->cur_attval = string;
3776  values[m] = InputFunctionCall(&in_functions[m],
3777  string,
3778  typioparams[m],
3779  att->atttypmod);
3780  if (string != NULL)
3781  nulls[m] = false;
3782  cstate->cur_attname = NULL;
3783  cstate->cur_attval = NULL;
3784  }
3785 
3786  Assert(fieldno == attr_count);
3787  }
3788  else
3789  {
3790  /* binary */
3791  int16 fld_count;
3792  ListCell *cur;
3793 
3794  cstate->cur_lineno++;
3795 
3796  if (!CopyGetInt16(cstate, &fld_count))
3797  {
3798  /* EOF detected (end of file, or protocol-level EOF) */
3799  return false;
3800  }
3801 
3802  if (fld_count == -1)
3803  {
3804  /*
3805  * Received EOF marker. In a V3-protocol copy, wait for the
3806  * protocol-level EOF, and complain if it doesn't come
3807  * immediately. This ensures that we correctly handle CopyFail,
3808  * if client chooses to send that now.
3809  *
3810  * Note that we MUST NOT try to read more data in an old-protocol
3811  * copy, since there is no protocol-level EOF marker then. We
3812  * could go either way for copy from file, but choose to throw
3813  * error if there's data after the EOF marker, for consistency
3814  * with the new-protocol case.
3815  */
3816  char dummy;
3817 
3818  if (cstate->copy_dest != COPY_OLD_FE &&
3819  CopyGetData(cstate, &dummy, 1, 1) > 0)
3820  ereport(ERROR,
3821  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3822  errmsg("received copy data after EOF marker")));
3823  return false;
3824  }
3825 
3826  if (fld_count != attr_count)
3827  ereport(ERROR,
3828  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3829  errmsg("row field count is %d, expected %d",
3830  (int) fld_count, attr_count)));
3831 
3832  i = 0;
3833  foreach(cur, cstate->attnumlist)
3834  {
3835  int attnum = lfirst_int(cur);
3836  int m = attnum - 1;
3837  Form_pg_attribute att = TupleDescAttr(tupDesc, m);
3838 
3839  cstate->cur_attname = NameStr(att->attname);
3840  i++;
3841  values[m] = CopyReadBinaryAttribute(cstate,
3842  i,
3843  &in_functions[m],
3844  typioparams[m],
3845  att->atttypmod,
3846  &nulls[m]);
3847  cstate->cur_attname = NULL;
3848  }
3849  }
3850 
3851  /*
3852  * Now compute and insert any defaults available for the columns not
3853  * provided by the input data. Anything not processed here or above will
3854  * remain NULL.
3855  */
3856  for (i = 0; i < num_defaults; i++)
3857  {
3858  /*
3859  * The caller must supply econtext and have switched into the
3860  * per-tuple memory context in it.
3861  */
3862  Assert(econtext != NULL);
3864 
3865  values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
3866  &nulls[defmap[i]]);
3867  }
3868 
3869  return true;
3870 }
signed short int16
Definition: c.h:345
bool NextCopyFromRawFields(CopyState cstate, char ***fields, int *nfields)
Definition: copy.c:3636
static Datum CopyReadBinaryAttribute(CopyState cstate, int column_no, FmgrInfo *flinfo, Oid typioparam, int32 typmod, bool *isnull)
Definition: copy.c:4770
Definition: fmgr.h:56
bool csv_mode
Definition: copy.c:138
bool binary
Definition: copy.c:136
#define RelationGetDescr(relation)
Definition: rel.h:445
FmgrInfo * in_functions
Definition: copy.c:179
AttrNumber num_defaults
Definition: copy.c:178
List * attnumlist
Definition: copy.c:132
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:232
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:570
#define MemSet(start, val, len)
Definition: c.h:955
unsigned int Oid
Definition: postgres_ext.h:31
bool * force_null_flags
Definition: copy.c:152
bool * convert_select_flags
Definition: copy.c:155
CopyDest copy_dest
Definition: copy.c:117
uint64 cur_lineno
Definition: copy.c:160
char * null_print
Definition: copy.c:140
const char * cur_attname
Definition: copy.c:161
Relation rel
Definition: copy.c:130
#define ERROR
Definition: elog.h:43
static int CopyGetData(CopyState cstate, void *databuf, int minread, int maxread)
Definition: copy.c:611
#define lfirst_int(lc)
Definition: pg_list.h:191
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:285
ExprState ** defexprs
Definition: copy.c:182
char string[11]
Definition: preproc-type.c:46
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define ereport(elevel, rest)
Definition: elog.h:141
Oid * typioparams
Definition: copy.c:180
uintptr_t Datum
Definition: postgres.h:367
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1531
int16 attnum
Definition: pg_attribute.h:79
bool * force_notnull_flags
Definition: copy.c:150
#define Assert(condition)
Definition: c.h:732
static int list_length(const List *l)
Definition: pg_list.h:169
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i
#define NameStr(name)
Definition: c.h:609
static bool CopyGetInt16(CopyState cstate, int16 *val)
Definition: copy.c:768
const char * cur_attval
Definition: copy.c:162
int16 AttrNumber
Definition: attnum.h:21
int * defmap
Definition: copy.c:181

◆ NextCopyFromRawFields()

bool NextCopyFromRawFields ( CopyState  cstate,
char ***  fields,
int *  nfields 
)

Definition at line 3636 of file copy.c.

References Assert, CopyStateData::binary, CopyReadAttributesCSV(), CopyReadAttributesText(), CopyReadLine(), CopyStateData::csv_mode, CopyStateData::cur_lineno, CopyStateData::header_line, StringInfoData::len, CopyStateData::line_buf, and CopyStateData::raw_fields.

Referenced by NextCopyFrom().

3637 {
3638  int fldct;
3639  bool done;
3640 
3641  /* only available for text or csv input */
3642  Assert(!cstate->binary);
3643 
3644  /* on input just throw the header line away */
3645  if (cstate->cur_lineno == 0 && cstate->header_line)
3646  {
3647  cstate->cur_lineno++;
3648  if (CopyReadLine(cstate))
3649  return false; /* done */
3650  }
3651 
3652  cstate->cur_lineno++;
3653 
3654  /* Actually read the line into memory here */
3655  done = CopyReadLine(cstate);
3656 
3657  /*
3658  * EOF at start of line means we're done. If we see EOF after some
3659  * characters, we act as though it was newline followed by EOF, ie,
3660  * process the line and then exit loop on next iteration.
3661  */
3662  if (done && cstate->line_buf.len == 0)
3663  return false;
3664 
3665  /* Parse the line into de-escaped field values */
3666  if (cstate->csv_mode)
3667  fldct = CopyReadAttributesCSV(cstate);
3668  else
3669  fldct = CopyReadAttributesText(cstate);
3670 
3671  *fields = cstate->raw_fields;
3672  *nfields = fldct;
3673  return true;
3674 }
bool csv_mode
Definition: copy.c:138
char ** raw_fields
Definition: copy.c:202
bool binary
Definition: copy.c:136
StringInfoData line_buf
Definition: copy.c:211
static int CopyReadAttributesCSV(CopyState cstate)
Definition: copy.c:4601
uint64 cur_lineno
Definition: copy.c:160
bool header_line
Definition: copy.c:139
#define Assert(condition)
Definition: c.h:732
static bool CopyReadLine(CopyState cstate)
Definition: copy.c:3892
static int CopyReadAttributesText(CopyState cstate)
Definition: copy.c:4373

◆ ProcessCopyOptions()

void ProcessCopyOptions ( ParseState pstate,
CopyState  cstate,
bool  is_from,
List options 
)

Definition at line 1110 of file copy.c.

References DefElem::arg, CopyStateData::binary, castNode, CopyStateData::convert_select, CopyStateData::convert_selectively, CopyStateData::csv_mode, defGetBoolean(), defGetString(), DefElem::defname, CopyStateData::delim, ereport, errcode(), errmsg(), ERROR, CopyStateData::escape, CopyStateData::file_encoding, CopyStateData::force_notnull, CopyStateData::force_null, CopyStateData::force_quote, CopyStateData::force_quote_all, CopyStateData::freeze, CopyStateData::header_line, CopyStateData::is_copy_from, IsA, lfirst_node, DefElem::location, NIL, CopyStateData::null_print, CopyStateData::null_print_len, palloc0(), parser_errposition(), pg_char_to_encoding(), and CopyStateData::quote.

Referenced by BeginCopy(), and file_fdw_validator().

1114 {
1115  bool format_specified = false;
1116  ListCell *option;
1117 
1118  /* Support external use for option sanity checking */
1119  if (cstate == NULL)
1120  cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
1121 
1122  cstate->is_copy_from = is_from;
1123 
1124  cstate->file_encoding = -1;
1125 
1126  /* Extract options from the statement node tree */
1127  foreach(option, options)
1128  {
1129  DefElem *defel = lfirst_node(DefElem, option);
1130 
1131  if (strcmp(defel->defname, "format") == 0)
1132  {
1133  char *fmt = defGetString(defel);
1134 
1135  if (format_specified)
1136  ereport(ERROR,
1137  (errcode(ERRCODE_SYNTAX_ERROR),
1138  errmsg("conflicting or redundant options"),
1139  parser_errposition(pstate, defel->location)));
1140  format_specified = true;
1141  if (strcmp(fmt, "text") == 0)
1142  /* default format */ ;
1143  else if (strcmp(fmt, "csv") == 0)
1144  cstate->csv_mode = true;
1145  else if (strcmp(fmt, "binary") == 0)
1146  cstate->binary = true;
1147  else
1148  ereport(ERROR,
1149  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1150  errmsg("COPY format \"%s\" not recognized", fmt),
1151  parser_errposition(pstate, defel->location)));
1152  }
1153  else if (strcmp(defel->defname, "freeze") == 0)
1154  {
1155  if (cstate->freeze)
1156  ereport(ERROR,
1157  (errcode(ERRCODE_SYNTAX_ERROR),
1158  errmsg("conflicting or redundant options"),
1159  parser_errposition(pstate, defel->location)));
1160  cstate->freeze = defGetBoolean(defel);
1161  }
1162  else if (strcmp(defel->defname, "delimiter") == 0)
1163  {
1164  if (cstate->delim)
1165  ereport(ERROR,
1166  (errcode(ERRCODE_SYNTAX_ERROR),
1167  errmsg("conflicting or redundant options"),
1168  parser_errposition(pstate, defel->location)));
1169  cstate->delim = defGetString(defel);
1170  }
1171  else if (strcmp(defel->defname, "null") == 0)
1172  {
1173  if (cstate->null_print)
1174  ereport(ERROR,
1175  (errcode(ERRCODE_SYNTAX_ERROR),
1176  errmsg("conflicting or redundant options"),
1177  parser_errposition(pstate, defel->location)));
1178  cstate->null_print = defGetString(defel);
1179  }
1180  else if (strcmp(defel->defname, "header") == 0)
1181  {
1182  if (cstate->header_line)
1183  ereport(ERROR,
1184  (errcode(ERRCODE_SYNTAX_ERROR),
1185  errmsg("conflicting or redundant options"),
1186  parser_errposition(pstate, defel->location)));
1187  cstate->header_line = defGetBoolean(defel);
1188  }
1189  else if (strcmp(defel->defname, "quote") == 0)
1190  {
1191  if (cstate->quote)
1192  ereport(ERROR,
1193  (errcode(ERRCODE_SYNTAX_ERROR),
1194  errmsg("conflicting or redundant options"),
1195  parser_errposition(pstate, defel->location)));
1196  cstate->quote = defGetString(defel);
1197  }
1198  else if (strcmp(defel->defname, "escape") == 0)
1199  {
1200  if (cstate->escape)
1201  ereport(ERROR,
1202  (errcode(ERRCODE_SYNTAX_ERROR),
1203  errmsg("conflicting or redundant options"),
1204  parser_errposition(pstate, defel->location)));
1205  cstate->escape = defGetString(defel);
1206  }
1207  else if (strcmp(defel->defname, "force_quote") == 0)
1208  {
1209  if (cstate->force_quote || cstate->force_quote_all)
1210  ereport(ERROR,
1211  (errcode(ERRCODE_SYNTAX_ERROR),
1212  errmsg("conflicting or redundant options"),
1213  parser_errposition(pstate, defel->location)));
1214  if (defel->arg && IsA(defel->arg, A_Star))
1215  cstate->force_quote_all = true;
1216  else if (defel->arg && IsA(defel->arg, List))
1217  cstate->force_quote = castNode(List, defel->arg);
1218  else
1219  ereport(ERROR,
1220  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1221  errmsg("argument to option \"%s\" must be a list of column names",
1222  defel->defname),
1223  parser_errposition(pstate, defel->location)));
1224  }
1225  else if (strcmp(defel->defname, "force_not_null") == 0)
1226  {
1227  if (cstate->force_notnull)
1228  ereport(ERROR,
1229  (errcode(ERRCODE_SYNTAX_ERROR),
1230  errmsg("conflicting or redundant options"),
1231  parser_errposition(pstate, defel->location)));
1232  if (defel->arg && IsA(defel->arg, List))
1233  cstate->force_notnull = castNode(List, defel->arg);
1234  else
1235  ereport(ERROR,
1236  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1237  errmsg("argument to option \"%s\" must be a list of column names",
1238  defel->defname),
1239  parser_errposition(pstate, defel->location)));
1240  }
1241  else if (strcmp(defel->defname, "force_null") == 0)
1242  {
1243  if (cstate->force_null)
1244  ereport(ERROR,
1245  (errcode(ERRCODE_SYNTAX_ERROR),
1246  errmsg("conflicting or redundant options")));
1247  if (defel->arg && IsA(defel->arg, List))
1248  cstate->force_null = castNode(List, defel->arg);
1249  else
1250  ereport(ERROR,
1251  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1252  errmsg("argument to option \"%s\" must be a list of column names",
1253  defel->defname),
1254  parser_errposition(pstate, defel->location)));
1255  }
1256  else if (strcmp(defel->defname, "convert_selectively") == 0)
1257  {
1258  /*
1259  * Undocumented, not-accessible-from-SQL option: convert only the
1260  * named columns to binary form, storing the rest as NULLs. It's
1261  * allowed for the column list to be NIL.
1262  */
1263  if (cstate->convert_selectively)
1264  ereport(ERROR,
1265  (errcode(ERRCODE_SYNTAX_ERROR),
1266  errmsg("conflicting or redundant options"),
1267  parser_errposition(pstate, defel->location)));
1268  cstate->convert_selectively = true;
1269  if (defel->arg == NULL || IsA(defel->arg, List))
1270  cstate->convert_select = castNode(List, defel->arg);
1271  else
1272  ereport(ERROR,
1273  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1274  errmsg("argument to option \"%s\" must be a list of column names",
1275  defel->defname),
1276  parser_errposition(pstate, defel->location)));
1277  }
1278  else if (strcmp(defel->defname, "encoding") == 0)
1279  {
1280  if (cstate->file_encoding >= 0)
1281  ereport(ERROR,
1282  (errcode(ERRCODE_SYNTAX_ERROR),
1283  errmsg("conflicting or redundant options"),
1284  parser_errposition(pstate, defel->location)));
1286  if (cstate->file_encoding < 0)
1287  ereport(ERROR,
1288  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1289  errmsg("argument to option \"%s\" must be a valid encoding name",
1290  defel->defname),
1291  parser_errposition(pstate, defel->location)));
1292  }
1293  else
1294  ereport(ERROR,
1295  (errcode(ERRCODE_SYNTAX_ERROR),
1296  errmsg("option \"%s\" not recognized",
1297  defel->defname),
1298  parser_errposition(pstate, defel->location)));
1299  }
1300 
1301  /*
1302  * Check for incompatible options (must do these two before inserting
1303  * defaults)
1304  */
1305  if (cstate->binary && cstate->delim)
1306  ereport(ERROR,
1307  (errcode(ERRCODE_SYNTAX_ERROR),
1308  errmsg("cannot specify DELIMITER in BINARY mode")));
1309 
1310  if (cstate->binary && cstate->null_print)
1311  ereport(ERROR,
1312  (errcode(ERRCODE_SYNTAX_ERROR),
1313  errmsg("cannot specify NULL in BINARY mode")));
1314 
1315  /* Set defaults for omitted options */
1316  if (!cstate->delim)
1317  cstate->delim = cstate->csv_mode ? "," : "\t";
1318 
1319  if (!cstate->null_print)
1320  cstate->null_print = cstate->csv_mode ? "" : "\\N";
1321  cstate->null_print_len = strlen(cstate->null_print);
1322 
1323  if (cstate->csv_mode)
1324  {
1325  if (!cstate->quote)
1326  cstate->quote = "\"";
1327  if (!cstate->escape)
1328  cstate->escape = cstate->quote;
1329  }
1330 
1331  /* Only single-byte delimiter strings are supported. */
1332  if (strlen(cstate->delim) != 1)
1333  ereport(ERROR,
1334  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1335  errmsg("COPY delimiter must be a single one-byte character")));
1336 
1337  /* Disallow end-of-line characters */
1338  if (strchr(cstate->delim, '\r') != NULL ||
1339  strchr(cstate->delim, '\n') != NULL)
1340  ereport(ERROR,
1341  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1342  errmsg("COPY delimiter cannot be newline or carriage return")));
1343 
1344  if (strchr(cstate->null_print, '\r') != NULL ||
1345  strchr(cstate->null_print, '\n') != NULL)
1346  ereport(ERROR,
1347  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1348  errmsg("COPY null representation cannot use newline or carriage return")));
1349 
1350  /*
1351  * Disallow unsafe delimiter characters in non-CSV mode. We can't allow
1352  * backslash because it would be ambiguous. We can't allow the other
1353  * cases because data characters matching the delimiter must be
1354  * backslashed, and certain backslash combinations are interpreted
1355  * non-literally by COPY IN. Disallowing all lower case ASCII letters is
1356  * more than strictly necessary, but seems best for consistency and
1357  * future-proofing. Likewise we disallow all digits though only octal
1358  * digits are actually dangerous.
1359  */
1360  if (!cstate->csv_mode &&
1361  strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
1362  cstate->delim[0]) != NULL)
1363  ereport(ERROR,
1364  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1365  errmsg("COPY delimiter cannot be \"%s\"", cstate->delim)));
1366 
1367  /* Check header */
1368  if (!cstate->csv_mode && cstate->header_line)
1369  ereport(ERROR,
1370  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1371  errmsg("COPY HEADER available only in CSV mode")));
1372 
1373  /* Check quote */
1374  if (!cstate->csv_mode && cstate->quote != NULL)
1375  ereport(ERROR,
1376  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1377  errmsg("COPY quote available only in CSV mode")));
1378 
1379  if (cstate->csv_mode && strlen(cstate->quote) != 1)
1380  ereport(ERROR,
1381  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1382  errmsg("COPY quote must be a single one-byte character")));
1383 
1384  if (cstate->csv_mode && cstate->delim[0] == cstate->quote[0])
1385  ereport(ERROR,
1386  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1387  errmsg("COPY delimiter and quote must be different")));
1388 
1389  /* Check escape */
1390  if (!cstate->csv_mode && cstate->escape != NULL)
1391  ereport(ERROR,
1392  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1393  errmsg("COPY escape available only in CSV mode")));
1394 
1395  if (cstate->csv_mode && strlen(cstate->escape) != 1)
1396  ereport(ERROR,
1397  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1398  errmsg("COPY escape must be a single one-byte character")));
1399 
1400  /* Check force_quote */
1401  if (!cstate->csv_mode && (cstate->force_quote || cstate->force_quote_all))
1402  ereport(ERROR,
1403  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1404  errmsg("COPY force quote available only in CSV mode")));
1405  if ((cstate->force_quote || cstate->force_quote_all) && is_from)
1406  ereport(ERROR,
1407  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1408  errmsg("COPY force quote only available using COPY TO")));
1409 
1410  /* Check force_notnull */
1411  if (!cstate->csv_mode && cstate->force_notnull != NIL)
1412  ereport(ERROR,
1413  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1414  errmsg("COPY force not null available only in CSV mode")));
1415  if (cstate->force_notnull != NIL && !is_from)
1416  ereport(ERROR,
1417  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1418  errmsg("COPY force not null only available using COPY FROM")));
1419 
1420  /* Check force_null */
1421  if (!cstate->csv_mode && cstate->force_null != NIL)
1422  ereport(ERROR,
1423  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1424  errmsg("COPY force null available only in CSV mode")));
1425 
1426  if (cstate->force_null != NIL && !is_from)
1427  ereport(ERROR,
1428  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1429  errmsg("COPY force null only available using COPY FROM")));
1430 
1431  /* Don't allow the delimiter to appear in the null string. */
1432  if (strchr(cstate->null_print, cstate->delim[0]) != NULL)
1433  ereport(ERROR,
1434  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1435  errmsg("COPY delimiter must not appear in the NULL specification")));
1436 
1437  /* Don't allow the CSV quote char to appear in the null string. */
1438  if (cstate->csv_mode &&
1439  strchr(cstate->null_print, cstate->quote[0]) != NULL)
1440  ereport(ERROR,
1441  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1442  errmsg("CSV quote character must not appear in the NULL specification")));
1443 }
#define NIL
Definition: pg_list.h:65
bool csv_mode
Definition: copy.c:138
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
int pg_char_to_encoding(const char *name)
Definition: encnames.c:551
bool binary
Definition: copy.c:136
#define castNode(_type_, nodeptr)
Definition: nodes.h:594
int errcode(int sqlerrcode)
Definition: elog.c:570
char * delim
Definition: copy.c:143
char * null_print
Definition: copy.c:140
bool defGetBoolean(DefElem *def)
Definition: define.c:111
#define ERROR
Definition: elog.h:43
char * defGetString(DefElem *def)
Definition: define.c:49
#define lfirst_node(type, lc)
Definition: pg_list.h:193
char * quote
Definition: copy.c:144
int location
Definition: parsenodes.h:733
bool is_copy_from
Definition: copy.c:121
char * escape
Definition: copy.c:145
#define ereport(elevel, rest)
Definition: elog.h:141
int null_print_len
Definition: copy.c:141
List * force_null
Definition: copy.c:151
Node * arg
Definition: parsenodes.h:731
int file_encoding
Definition: copy.c:125
void * palloc0(Size size)
Definition: mcxt.c:980
bool header_line
Definition: copy.c:139
bool freeze
Definition: copy.c:137
List * force_notnull
Definition: copy.c:149
List * convert_select
Definition: copy.c:154
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
bool force_quote_all
Definition: copy.c:147
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * defname
Definition: parsenodes.h:730
Definition: pg_list.h:50
List * force_quote
Definition: copy.c:146
bool convert_selectively
Definition: copy.c:153