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 3384 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().

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

◆ CopyFrom()

uint64 CopyFrom ( CopyState  cstate)

Definition at line 2655 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().

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

◆ CopyFromErrorCallback()

void CopyFromErrorCallback ( void *  arg)

Definition at line 2236 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().

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

◆ CreateCopyDestReceiver()

DestReceiver* CreateCopyDestReceiver ( void  )

Definition at line 5199 of file copy.c.

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

Referenced by CreateDestReceiver().

5200 {
5201  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
5202 
5203  self->pub.receiveSlot = copy_dest_receive;
5204  self->pub.rStartup = copy_dest_startup;
5205  self->pub.rShutdown = copy_dest_shutdown;
5206  self->pub.rDestroy = copy_dest_destroy;
5207  self->pub.mydest = DestCopyOut;
5208 
5209  self->cstate = NULL; /* will be set later */
5210  self->processed = 0;
5211 
5212  return (DestReceiver *) self;
5213 }
Definition: copy.c:228
static void copy_dest_destroy(DestReceiver *self)
Definition: copy.c:5190
static void copy_dest_shutdown(DestReceiver *self)
Definition: copy.c:5181
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copy.c:5156
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copy.c:5165
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 837 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().

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

◆ EndCopyFrom()

void EndCopyFrom ( CopyState  cstate)

Definition at line 3873 of file copy.c.

References EndCopy().

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

3874 {
3875  /* No COPY FROM related resources except memory. */
3876 
3877  EndCopy(cstate);
3878 }
static void EndCopy(CopyState cstate)
Definition: copy.c:1801

◆ NextCopyFrom()

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

Definition at line 3685 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().

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

◆ NextCopyFromRawFields()

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

Definition at line 3633 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().

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

◆ ProcessCopyOptions()

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

Definition at line 1109 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().

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