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

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

◆ CopyFrom()

uint64 CopyFrom ( CopyState  cstate)

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

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

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

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

Referenced by CreateDestReceiver().

5201 {
5202  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
5203 
5204  self->pub.receiveSlot = copy_dest_receive;
5205  self->pub.rStartup = copy_dest_startup;
5206  self->pub.rShutdown = copy_dest_shutdown;
5207  self->pub.rDestroy = copy_dest_destroy;
5208  self->pub.mydest = DestCopyOut;
5209 
5210  self->cstate = NULL; /* will be set later */
5211  self->processed = 0;
5212 
5213  return (DestReceiver *) self;
5214 }
Definition: copy.c:228
static void copy_dest_destroy(DestReceiver *self)
Definition: copy.c:5191
static void copy_dest_shutdown(DestReceiver *self)
Definition: copy.c:5182
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copy.c:5157
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copy.c:5166
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, addNSItemToQuery(), addRangeTableEntryForRelation(), 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, ParseNamespaceItem::p_rte, 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  ParseNamespaceItem *nsitem;
886  RangeTblEntry *rte;
887  TupleDesc tupDesc;
888  List *attnums;
889  ListCell *cur;
890 
891  Assert(!stmt->query);
892 
893  /* Open and lock the relation, using the appropriate lock type. */
894  rel = table_openrv(stmt->relation, lockmode);
895 
896  relid = RelationGetRelid(rel);
897 
898  nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
899  NULL, false, false);
900  rte = nsitem->p_rte;
901  rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
902 
903  if (stmt->whereClause)
904  {
905  /* add nsitem to query namespace */
906  addNSItemToQuery(pstate, nsitem, false, true, true);
907 
908  /* Transform the raw expression tree */
909  whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
910 
911  /* Make sure it yields a boolean result. */
912  whereClause = coerce_to_boolean(pstate, whereClause, "WHERE");
913 
914  /* we have to fix its collations too */
915  assign_expr_collations(pstate, whereClause);
916 
917  whereClause = eval_const_expressions(NULL, whereClause);
918 
919  whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
920  whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
921  }
922 
923  tupDesc = RelationGetDescr(rel);
924  attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
925  foreach(cur, attnums)
926  {
927  int attno = lfirst_int(cur) -
929 
930  if (is_from)
931  rte->insertedCols = bms_add_member(rte->insertedCols, attno);
932  else
933  rte->selectedCols = bms_add_member(rte->selectedCols, attno);
934  }
935  ExecCheckRTPerms(pstate->p_rtable, true);
936 
937  /*
938  * Permission check for row security policies.
939  *
940  * check_enable_rls will ereport(ERROR) if the user has requested
941  * something invalid and will otherwise indicate if we should enable
942  * RLS (returns RLS_ENABLED) or not for this COPY statement.
943  *
944  * If the relation has a row security policy and we are to apply it
945  * then perform a "query" copy and allow the normal query processing
946  * to handle the policies.
947  *
948  * If RLS is not enabled for this, then just fall through to the
949  * normal non-filtering relation handling.
950  */
951  if (check_enable_rls(rte->relid, InvalidOid, false) == RLS_ENABLED)
952  {
954  ColumnRef *cr;
955  ResTarget *target;
956  RangeVar *from;
957  List *targetList = NIL;
958 
959  if (is_from)
960  ereport(ERROR,
961  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
962  errmsg("COPY FROM not supported with row-level security"),
963  errhint("Use INSERT statements instead.")));
964 
965  /*
966  * Build target list
967  *
968  * If no columns are specified in the attribute list of the COPY
969  * command, then the target list is 'all' columns. Therefore, '*'
970  * should be used as the target list for the resulting SELECT
971  * statement.
972  *
973  * In the case that columns are specified in the attribute list,
974  * create a ColumnRef and ResTarget for each column and add them
975  * to the target list for the resulting SELECT statement.
976  */
977  if (!stmt->attlist)
978  {
979  cr = makeNode(ColumnRef);
981  cr->location = -1;
982 
983  target = makeNode(ResTarget);
984  target->name = NULL;
985  target->indirection = NIL;
986  target->val = (Node *) cr;
987  target->location = -1;
988 
989  targetList = list_make1(target);
990  }
991  else
992  {
993  ListCell *lc;
994 
995  foreach(lc, stmt->attlist)
996  {
997  /*
998  * Build the ColumnRef for each column. The ColumnRef
999  * 'fields' property is a String 'Value' node (see
1000  * nodes/value.h) that corresponds to the column name
1001  * respectively.
1002  */
1003  cr = makeNode(ColumnRef);
1004  cr->fields = list_make1(lfirst(lc));
1005  cr->location = -1;
1006 
1007  /* Build the ResTarget and add the ColumnRef to it. */
1008  target = makeNode(ResTarget);
1009  target->name = NULL;
1010  target->indirection = NIL;
1011  target->val = (Node *) cr;
1012  target->location = -1;
1013 
1014  /* Add each column to the SELECT statement's target list */
1015  targetList = lappend(targetList, target);
1016  }
1017  }
1018 
1019  /*
1020  * Build RangeVar for from clause, fully qualified based on the
1021  * relation which we have opened and locked.
1022  */
1025  -1);
1026 
1027  /* Build query */
1028  select = makeNode(SelectStmt);
1029  select->targetList = targetList;
1030  select->fromClause = list_make1(from);
1031 
1032  query = makeNode(RawStmt);
1033  query->stmt = (Node *) select;
1034  query->stmt_location = stmt_location;
1035  query->stmt_len = stmt_len;
1036 
1037  /*
1038  * Close the relation for now, but keep the lock on it to prevent
1039  * changes between now and when we start the query-based COPY.
1040  *
1041  * We'll reopen it later as part of the query-based COPY.
1042  */
1043  table_close(rel, NoLock);
1044  rel = NULL;
1045  }
1046  }
1047  else
1048  {
1049  Assert(stmt->query);
1050 
1051  query = makeNode(RawStmt);
1052  query->stmt = stmt->query;
1053  query->stmt_location = stmt_location;
1054  query->stmt_len = stmt_len;
1055 
1056  relid = InvalidOid;
1057  rel = NULL;
1058  }
1059 
1060  if (is_from)
1061  {
1062  Assert(rel);
1063 
1064  /* check read-only transaction and parallel mode */
1065  if (XactReadOnly && !rel->rd_islocaltemp)
1066  PreventCommandIfReadOnly("COPY FROM");
1067 
1068  cstate = BeginCopyFrom(pstate, rel, stmt->filename, stmt->is_program,
1069  NULL, stmt->attlist, stmt->options);
1070  cstate->whereClause = whereClause;
1071  *processed = CopyFrom(cstate); /* copy from file to database */
1072  EndCopyFrom(cstate);
1073  }
1074  else
1075  {
1076  cstate = BeginCopyTo(pstate, rel, query, relid,
1077  stmt->filename, stmt->is_program,
1078  stmt->attlist, stmt->options);
1079  *processed = DoCopyTo(cstate); /* copy from database to file */
1080  EndCopyTo(cstate);
1081  }
1082 
1083  /*
1084  * Close the relation. If reading, we can release the AccessShareLock we
1085  * got; if writing, we should hold the lock until end of transaction to
1086  * ensure that updates will be committed before lock is released.
1087  */
1088  if (rel != NULL)
1089  table_close(rel, (is_from ? NoLock : AccessShareLock));
1090 }
List * indirection
Definition: parsenodes.h:441
Node * whereClause
Definition: copy.c:155
#define NIL
Definition: pg_list.h:65
Node * whereClause
Definition: parsenodes.h:2016
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
List * attlist
Definition: parsenodes.h:2010
List * fromClause
Definition: parsenodes.h:1596
#define RelationGetDescr(relation)
Definition: rel.h:454
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:3385
char * pstrdup(const char *in)
Definition: mcxt.c:1186
bool rd_islocaltemp
Definition: rel.h:60
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:145
#define AccessShareLock
Definition: lockdefs.h:36
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
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:2252
uint64 CopyFrom(CopyState cstate)
Definition: copy.c:2656
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
AclMode requiredPerms
Definition: parsenodes.h:1117
unsigned int Oid
Definition: postgres_ext.h:31
bool is_program
Definition: parsenodes.h:2013
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
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)
RangeTblEntry * p_rte
Definition: parse_node.h:257
Bitmapset * selectedCols
Definition: parsenodes.h:1119
static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, Oid queryRelId, const char *filename, bool is_program, List *attnamelist, List *options)
Definition: copy.c:1825
#define ERROR
Definition: elog.h:43
#define lfirst_int(lc)
Definition: pg_list.h:191
RangeVar * relation
Definition: parsenodes.h:2007
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
Node * stmt
Definition: parsenodes.h:1506
#define NoLock
Definition: lockdefs.h:34
List * targetList
Definition: parsenodes.h:1595
static uint64 DoCopyTo(CopyState cstate)
Definition: copy.c:1961
#define RowExclusiveLock
Definition: lockdefs.h:38
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:292
List * options
Definition: parsenodes.h:2015
#define select(n, r, w, e, timeout)
Definition: win32_port.h:436
#define RelationGetRelationName(relation)
Definition: rel.h:462
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
static List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:5076
#define ACL_SELECT
Definition: parsenodes.h:75
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:716
int stmt_len
Definition: parsenodes.h:1508
int stmt_location
Definition: parsenodes.h:1507
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:3874
#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:405
Node * query
Definition: parsenodes.h:2008
bool is_from
Definition: parsenodes.h:2012
int errmsg(const char *fmt,...)
Definition: elog.c:822
Bitmapset * insertedCols
Definition: parsenodes.h:1120
bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation)
Definition: execMain.c:571
char * filename
Definition: parsenodes.h:2014
static void EndCopyTo(CopyState cstate)
Definition: copy.c:1996
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:428
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420
List * fields
Definition: parsenodes.h:235
#define RelationGetNamespace(relation)
Definition: rel.h:469
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)

◆ EndCopyFrom()

void EndCopyFrom ( CopyState  cstate)

Definition at line 3874 of file copy.c.

References EndCopy().

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

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

◆ NextCopyFrom()

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

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

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

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

◆ ProcessCopyOptions()

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

Definition at line 1110 of file copy.c.

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

Referenced by BeginCopy(), and file_fdw_validator().

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