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 3355 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, CopyGetInt32(), CopyReadBinaryData(), 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(), fstat, 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::st_mode, TupleDescAttr, CopyStateData::typioparams, CopyStateData::volatile_defexprs, and whereToSendOutput.

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

3362 {
3363  CopyState cstate;
3364  bool pipe = (filename == NULL);
3365  TupleDesc tupDesc;
3366  AttrNumber num_phys_attrs,
3367  num_defaults;
3368  FmgrInfo *in_functions;
3369  Oid *typioparams;
3370  int attnum;
3371  Oid in_func_oid;
3372  int *defmap;
3373  ExprState **defexprs;
3374  MemoryContext oldcontext;
3375  bool volatile_defexprs;
3376 
3377  cstate = BeginCopy(pstate, true, rel, NULL, InvalidOid, attnamelist, options);
3378  oldcontext = MemoryContextSwitchTo(cstate->copycontext);
3379 
3380  /* Initialize state variables */
3381  cstate->reached_eof = false;
3382  cstate->eol_type = EOL_UNKNOWN;
3383  cstate->cur_relname = RelationGetRelationName(cstate->rel);
3384  cstate->cur_lineno = 0;
3385  cstate->cur_attname = NULL;
3386  cstate->cur_attval = NULL;
3387 
3388  /*
3389  * Set up variables to avoid per-attribute overhead. attribute_buf and
3390  * raw_buf are used in both text and binary modes, but we use line_buf
3391  * only in text mode.
3392  */
3393  initStringInfo(&cstate->attribute_buf);
3394  cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
3395  cstate->raw_buf_index = cstate->raw_buf_len = 0;
3396  if (!cstate->binary)
3397  {
3398  initStringInfo(&cstate->line_buf);
3399  cstate->line_buf_converted = false;
3400  }
3401 
3402  /* Assign range table, we'll need it in CopyFrom. */
3403  if (pstate)
3404  cstate->range_table = pstate->p_rtable;
3405 
3406  tupDesc = RelationGetDescr(cstate->rel);
3407  num_phys_attrs = tupDesc->natts;
3408  num_defaults = 0;
3409  volatile_defexprs = false;
3410 
3411  /*
3412  * Pick up the required catalog information for each attribute in the
3413  * relation, including the input function, the element type (to pass to
3414  * the input function), and info about defaults and constraints. (Which
3415  * input function we use depends on text/binary format choice.)
3416  */
3417  in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
3418  typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
3419  defmap = (int *) palloc(num_phys_attrs * sizeof(int));
3420  defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
3421 
3422  for (attnum = 1; attnum <= num_phys_attrs; attnum++)
3423  {
3424  Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
3425 
3426  /* We don't need info for dropped attributes */
3427  if (att->attisdropped)
3428  continue;
3429 
3430  /* Fetch the input function and typioparam info */
3431  if (cstate->binary)
3432  getTypeBinaryInputInfo(att->atttypid,
3433  &in_func_oid, &typioparams[attnum - 1]);
3434  else
3435  getTypeInputInfo(att->atttypid,
3436  &in_func_oid, &typioparams[attnum - 1]);
3437  fmgr_info(in_func_oid, &in_functions[attnum - 1]);
3438 
3439  /* Get default info if needed */
3440  if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated)
3441  {
3442  /* attribute is NOT to be copied from input */
3443  /* use default value if one exists */
3444  Expr *defexpr = (Expr *) build_column_default(cstate->rel,
3445  attnum);
3446 
3447  if (defexpr != NULL)
3448  {
3449  /* Run the expression through planner */
3450  defexpr = expression_planner(defexpr);
3451 
3452  /* Initialize executable expression in copycontext */
3453  defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
3454  defmap[num_defaults] = attnum - 1;
3455  num_defaults++;
3456 
3457  /*
3458  * If a default expression looks at the table being loaded,
3459  * then it could give the wrong answer when using
3460  * multi-insert. Since database access can be dynamic this is
3461  * hard to test for exactly, so we use the much wider test of
3462  * whether the default expression is volatile. We allow for
3463  * the special case of when the default expression is the
3464  * nextval() of a sequence which in this specific case is
3465  * known to be safe for use with the multi-insert
3466  * optimization. Hence we use this special case function
3467  * checker rather than the standard check for
3468  * contain_volatile_functions().
3469  */
3470  if (!volatile_defexprs)
3471  volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr);
3472  }
3473  }
3474  }
3475 
3476  /* We keep those variables in cstate. */
3477  cstate->in_functions = in_functions;
3478  cstate->typioparams = typioparams;
3479  cstate->defmap = defmap;
3480  cstate->defexprs = defexprs;
3481  cstate->volatile_defexprs = volatile_defexprs;
3482  cstate->num_defaults = num_defaults;
3483  cstate->is_program = is_program;
3484 
3485  if (data_source_cb)
3486  {
3487  cstate->copy_dest = COPY_CALLBACK;
3488  cstate->data_source_cb = data_source_cb;
3489  }
3490  else if (pipe)
3491  {
3492  Assert(!is_program); /* the grammar does not allow this */
3494  ReceiveCopyBegin(cstate);
3495  else
3496  cstate->copy_file = stdin;
3497  }
3498  else
3499  {
3500  cstate->filename = pstrdup(filename);
3501 
3502  if (cstate->is_program)
3503  {
3504  cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R);
3505  if (cstate->copy_file == NULL)
3506  ereport(ERROR,
3508  errmsg("could not execute command \"%s\": %m",
3509  cstate->filename)));
3510  }
3511  else
3512  {
3513  struct stat st;
3514 
3515  cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
3516  if (cstate->copy_file == NULL)
3517  {
3518  /* copy errno because ereport subfunctions might change it */
3519  int save_errno = errno;
3520 
3521  ereport(ERROR,
3523  errmsg("could not open file \"%s\" for reading: %m",
3524  cstate->filename),
3525  (save_errno == ENOENT || save_errno == EACCES) ?
3526  errhint("COPY FROM instructs the PostgreSQL server process to read a file. "
3527  "You may want a client-side facility such as psql's \\copy.") : 0));
3528  }
3529 
3530  if (fstat(fileno(cstate->copy_file), &st))
3531  ereport(ERROR,
3533  errmsg("could not stat file \"%s\": %m",
3534  cstate->filename)));
3535 
3536  if (S_ISDIR(st.st_mode))
3537  ereport(ERROR,
3538  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3539  errmsg("\"%s\" is a directory", cstate->filename)));
3540  }
3541  }
3542 
3543  if (cstate->binary)
3544  {
3545  /* Read and verify binary header */
3546  char readSig[11];
3547  int32 tmp;
3548 
3549  /* Signature */
3550  if (CopyReadBinaryData(cstate, readSig, 11) != 11 ||
3551  memcmp(readSig, BinarySignature, 11) != 0)
3552  ereport(ERROR,
3553  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3554  errmsg("COPY file signature not recognized")));
3555  /* Flags field */
3556  if (!CopyGetInt32(cstate, &tmp))
3557  ereport(ERROR,
3558  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3559  errmsg("invalid COPY file header (missing flags)")));
3560  if ((tmp & (1 << 16)) != 0)
3561  ereport(ERROR,
3562  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3563  errmsg("invalid COPY file header (WITH OIDS)")));
3564  tmp &= ~(1 << 16);
3565  if ((tmp >> 16) != 0)
3566  ereport(ERROR,
3567  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3568  errmsg("unrecognized critical flags in COPY file header")));
3569  /* Header extension length */
3570  if (!CopyGetInt32(cstate, &tmp) ||
3571  tmp < 0)
3572  ereport(ERROR,
3573  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3574  errmsg("invalid COPY file header (missing length)")));
3575  /* Skip extension header, if present */
3576  while (tmp-- > 0)
3577  {
3578  if (CopyReadBinaryData(cstate, readSig, 1) != 1)
3579  ereport(ERROR,
3580  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3581  errmsg("invalid COPY file header (wrong length)")));
3582  }
3583  }
3584 
3585  /* create workspace for CopyReadAttributes results */
3586  if (!cstate->binary)
3587  {
3588  AttrNumber attr_count = list_length(cstate->attnumlist);
3589 
3590  cstate->max_fields = attr_count;
3591  cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
3592  }
3593 
3594  MemoryContextSwitchTo(oldcontext);
3595 
3596  return cstate;
3597 }
Definition: fmgr.h:56
List * range_table
Definition: copy.c:184
static CopyState BeginCopy(ParseState *pstate, bool is_from, Relation rel, RawStmt *raw_query, Oid queryRelId, List *attnamelist, List *options)
Definition: copy.c:1511
bool contain_volatile_functions_not_nextval(Node *clause)
Definition: clauses.c:774
static bool CopyGetInt32(CopyState cstate, int32 *val)
Definition: copy.c:747
int errhint(const char *fmt,...)
Definition: elog.c:1068
char ** raw_fields
Definition: copy.c:205
bool binary
Definition: copy.c:136
#define RelationGetDescr(relation)
Definition: rel.h:482
AttrNumber num_defaults
Definition: copy.c:178
FmgrInfo * in_functions
Definition: copy.c:179
List * attnumlist
Definition: copy.c:132
char * filename
Definition: copy.c:133
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1187
static void ReceiveCopyBegin(CopyState cstate)
Definition: copy.c:443
Expr * expression_planner(Expr *expr)
Definition: planner.c:6174
StringInfoData line_buf
Definition: copy.c:215
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:528
int raw_buf_index
Definition: copy.c:229
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
bool volatile_defexprs
Definition: copy.c:183
#define PG_BINARY_R
Definition: c.h:1215
bool line_buf_converted
Definition: copy.c:216
signed int int32
Definition: c.h:363
CopyDest copy_dest
Definition: copy.c:117
uint64 cur_lineno
Definition: copy.c:160
const char * cur_attname
Definition: copy.c:161
Relation rel
Definition: copy.c:130
MemoryContext copycontext
Definition: copy.c:167
copy_data_source_cb data_source_cb
Definition: copy.c:135
#define fstat
Definition: win32_port.h:274
#define ERROR
Definition: elog.h:43
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
bool list_member_int(const List *list, int datum)
Definition: list.c:654
char * raw_buf
Definition: copy.c:228
ExprState ** defexprs
Definition: copy.c:182
const char * cur_relname
Definition: copy.c:159
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2322
#define RelationGetRelationName(relation)
Definition: rel.h:490
static const char BinarySignature[11]
Definition: copy.c:357
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
int raw_buf_len
Definition: copy.c:230
static int CopyReadBinaryData(CopyState cstate, char *dest, int nbytes)
Definition: copy.c:827
int max_fields
Definition: copy.c:204
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2425
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2817
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2751
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Oid * typioparams
Definition: copy.c:180
bool is_program
Definition: copy.c:134
Node * build_column_default(Relation rel, int attrno)
#define RAW_BUF_SIZE
Definition: copy.c:227
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:144
EolType eol_type
Definition: copy.c:124
#define Assert(condition)
Definition: c.h:746
bool reached_eof
Definition: copy.c:122
static int list_length(const List *l)
Definition: pg_list.h:149
#define S_ISDIR(m)
Definition: win32_port.h:316
static char * filename
Definition: pg_dumpall.c:91
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:821
FILE * copy_file
Definition: copy.c:118
StringInfoData attribute_buf
Definition: copy.c:200
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:123
const char * cur_attval
Definition: copy.c:162
CommandDest whereToSendOutput
Definition: postgres.c:91
int16 AttrNumber
Definition: attnum.h:21
int * defmap
Definition: copy.c:181
List * p_rtable
Definition: parse_node.h:180

◆ CopyFrom()

uint64 CopyFrom ( CopyState  cstate)

Definition at line 2704 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_tupleTable, ExecARInsertTriggers(), ExecASInsertTriggers(), ExecBRInsertTriggers(), ExecBSInsertTriggers(), ExecCleanupTupleRouting(), ExecClearTuple(), ExecCloseRangeTableRelations(), ExecCloseResultRelations(), ExecComputeStoredGenerated(), ExecConstraints(), ExecCopySlot(), ExecFindPartition(), FdwRoutine::ExecForeignInsert, ExecInitQual(), ExecInitRangeTable(), ExecInitResultRelation(), 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, InvalidateCatalogSnapshot(), InvalidSubTransactionId, StringInfoData::len, CopyStateData::line_buf, list_free(), list_length(), makeNode, MakeTransitionCaptureState(), MemoryContextSwitchTo(), ModifyTableState::mt_transition_capture, NextCopyFrom(), NIL, ModifyTableState::operation, PlanState::plan, pq_endmsgread(), ErrorContextCallback::previous, ModifyTableState::ps, CopyStateData::qualexpr, CopyStateData::range_table, RelationData::rd_att, RelationData::rd_createSubid, RelationData::rd_firstRelfilenodeSubid, 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_PartitionTupleSlot, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_RootToPartitionMap, ResultRelInfo::ri_TrigDesc, PlanState::state, TABLE_INSERT_FROZEN, TABLE_INSERT_SKIP_FSM, table_slot_create(), table_tuple_insert(), 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, and CopyStateData::whereClause.

Referenced by copy_table(), and DoCopy().

2705 {
2706  ResultRelInfo *resultRelInfo;
2707  ResultRelInfo *target_resultRelInfo;
2708  ResultRelInfo *prevResultRelInfo = NULL;
2709  EState *estate = CreateExecutorState(); /* for ExecConstraints() */
2710  ModifyTableState *mtstate;
2711  ExprContext *econtext;
2712  TupleTableSlot *singleslot = NULL;
2713  MemoryContext oldcontext = CurrentMemoryContext;
2714 
2715  PartitionTupleRouting *proute = NULL;
2716  ErrorContextCallback errcallback;
2717  CommandId mycid = GetCurrentCommandId(true);
2718  int ti_options = 0; /* start with default options for insert */
2719  BulkInsertState bistate = NULL;
2720  CopyInsertMethod insertMethod;
2721  CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
2722  uint64 processed = 0;
2723  bool has_before_insert_row_trig;
2724  bool has_instead_insert_row_trig;
2725  bool leafpart_use_multi_insert = false;
2726 
2727  Assert(cstate->rel);
2728  Assert(list_length(cstate->range_table) == 1);
2729 
2730  /*
2731  * The target must be a plain, foreign, or partitioned relation, or have
2732  * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
2733  * allowed on views, so we only hint about them in the view case.)
2734  */
2735  if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
2736  cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
2737  cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
2738  !(cstate->rel->trigdesc &&
2740  {
2741  if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
2742  ereport(ERROR,
2743  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2744  errmsg("cannot copy to view \"%s\"",
2745  RelationGetRelationName(cstate->rel)),
2746  errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
2747  else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
2748  ereport(ERROR,
2749  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2750  errmsg("cannot copy to materialized view \"%s\"",
2751  RelationGetRelationName(cstate->rel))));
2752  else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
2753  ereport(ERROR,
2754  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2755  errmsg("cannot copy to sequence \"%s\"",
2756  RelationGetRelationName(cstate->rel))));
2757  else
2758  ereport(ERROR,
2759  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2760  errmsg("cannot copy to non-table relation \"%s\"",
2761  RelationGetRelationName(cstate->rel))));
2762  }
2763 
2764  /*
2765  * If the target file is new-in-transaction, we assume that checking FSM
2766  * for free space is a waste of time. This could possibly be wrong, but
2767  * it's unlikely.
2768  */
2769  if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) &&
2772  ti_options |= TABLE_INSERT_SKIP_FSM;
2773 
2774  /*
2775  * Optimize if new relfilenode was created in this subxact or one of its
2776  * committed children and we won't see those rows later as part of an
2777  * earlier scan or command. The subxact test ensures that if this subxact
2778  * aborts then the frozen rows won't be visible after xact cleanup. Note
2779  * that the stronger test of exactly which subtransaction created it is
2780  * crucial for correctness of this optimization. The test for an earlier
2781  * scan or command tolerates false negatives. FREEZE causes other sessions
2782  * to see rows they would not see under MVCC, and a false negative merely
2783  * spreads that anomaly to the current session.
2784  */
2785  if (cstate->freeze)
2786  {
2787  /*
2788  * We currently disallow COPY FREEZE on partitioned tables. The
2789  * reason for this is that we've simply not yet opened the partitions
2790  * to determine if the optimization can be applied to them. We could
2791  * go and open them all here, but doing so may be quite a costly
2792  * overhead for small copies. In any case, we may just end up routing
2793  * tuples to a small number of partitions. It seems better just to
2794  * raise an ERROR for partitioned tables.
2795  */
2796  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2797  {
2798  ereport(ERROR,
2799  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2800  errmsg("cannot perform COPY FREEZE on a partitioned table")));
2801  }
2802 
2803  /*
2804  * Tolerate one registration for the benefit of FirstXactSnapshot.
2805  * Scan-bearing queries generally create at least two registrations,
2806  * though relying on that is fragile, as is ignoring ActiveSnapshot.
2807  * Clear CatalogSnapshot to avoid counting its registration. We'll
2808  * still detect ongoing catalog scans, each of which separately
2809  * registers the snapshot it uses.
2810  */
2813  ereport(ERROR,
2814  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2815  errmsg("cannot perform COPY FREEZE because of prior transaction activity")));
2816 
2817  if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() &&
2819  ereport(ERROR,
2820  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2821  errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction")));
2822 
2823  ti_options |= TABLE_INSERT_FROZEN;
2824  }
2825 
2826  /*
2827  * We need a ResultRelInfo so we can use the regular executor's
2828  * index-entry-making machinery. (There used to be a huge amount of code
2829  * here that basically duplicated execUtils.c ...)
2830  */
2831  ExecInitRangeTable(estate, cstate->range_table);
2832  resultRelInfo = target_resultRelInfo = makeNode(ResultRelInfo);
2833  ExecInitResultRelation(estate, resultRelInfo, 1);
2834 
2835  /* Verify the named relation is a valid target for INSERT */
2836  CheckValidResultRel(resultRelInfo, CMD_INSERT);
2837 
2838  ExecOpenIndices(resultRelInfo, false);
2839 
2840  /*
2841  * Set up a ModifyTableState so we can let FDW(s) init themselves for
2842  * foreign-table result relation(s).
2843  */
2844  mtstate = makeNode(ModifyTableState);
2845  mtstate->ps.plan = NULL;
2846  mtstate->ps.state = estate;
2847  mtstate->operation = CMD_INSERT;
2848  mtstate->resultRelInfo = resultRelInfo;
2849 
2850  if (resultRelInfo->ri_FdwRoutine != NULL &&
2851  resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
2852  resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate,
2853  resultRelInfo);
2854 
2855  /* Prepare to catch AFTER triggers. */
2857 
2858  /*
2859  * If there are any triggers with transition tables on the named relation,
2860  * we need to be prepared to capture transition tuples.
2861  *
2862  * Because partition tuple routing would like to know about whether
2863  * transition capture is active, we also set it in mtstate, which is
2864  * passed to ExecFindPartition() below.
2865  */
2866  cstate->transition_capture = mtstate->mt_transition_capture =
2868  RelationGetRelid(cstate->rel),
2869  CMD_INSERT);
2870 
2871  /*
2872  * If the named relation is a partitioned table, initialize state for
2873  * CopyFrom tuple routing.
2874  */
2875  if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2876  proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel);
2877 
2878  if (cstate->whereClause)
2879  cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
2880  &mtstate->ps);
2881 
2882  /*
2883  * It's generally more efficient to prepare a bunch of tuples for
2884  * insertion, and insert them in one table_multi_insert() call, than call
2885  * table_tuple_insert() separately for every tuple. However, there are a
2886  * number of reasons why we might not be able to do this. These are
2887  * explained below.
2888  */
2889  if (resultRelInfo->ri_TrigDesc != NULL &&
2890  (resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
2891  resultRelInfo->ri_TrigDesc->trig_insert_instead_row))
2892  {
2893  /*
2894  * Can't support multi-inserts when there are any BEFORE/INSTEAD OF
2895  * triggers on the table. Such triggers might query the table we're
2896  * inserting into and act differently if the tuples that have already
2897  * been processed and prepared for insertion are not there.
2898  */
2899  insertMethod = CIM_SINGLE;
2900  }
2901  else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL &&
2902  resultRelInfo->ri_TrigDesc->trig_insert_new_table)
2903  {
2904  /*
2905  * For partitioned tables we can't support multi-inserts when there
2906  * are any statement level insert triggers. It might be possible to
2907  * allow partitioned tables with such triggers in the future, but for
2908  * now, CopyMultiInsertInfoFlush expects that any before row insert
2909  * and statement level insert triggers are on the same relation.
2910  */
2911  insertMethod = CIM_SINGLE;
2912  }
2913  else if (resultRelInfo->ri_FdwRoutine != NULL ||
2914  cstate->volatile_defexprs)
2915  {
2916  /*
2917  * Can't support multi-inserts to foreign tables or if there are any
2918  * volatile default expressions in the table. Similarly to the
2919  * trigger case above, such expressions may query the table we're
2920  * inserting into.
2921  *
2922  * Note: It does not matter if any partitions have any volatile
2923  * default expressions as we use the defaults from the target of the
2924  * COPY command.
2925  */
2926  insertMethod = CIM_SINGLE;
2927  }
2928  else if (contain_volatile_functions(cstate->whereClause))
2929  {
2930  /*
2931  * Can't support multi-inserts if there are any volatile function
2932  * expressions in WHERE clause. Similarly to the trigger case above,
2933  * such expressions may query the table we're inserting into.
2934  */
2935  insertMethod = CIM_SINGLE;
2936  }
2937  else
2938  {
2939  /*
2940  * For partitioned tables, we may still be able to perform bulk
2941  * inserts. However, the possibility of this depends on which types
2942  * of triggers exist on the partition. We must disable bulk inserts
2943  * if the partition is a foreign table or it has any before row insert
2944  * or insert instead triggers (same as we checked above for the parent
2945  * table). Since the partition's resultRelInfos are initialized only
2946  * when we actually need to insert the first tuple into them, we must
2947  * have the intermediate insert method of CIM_MULTI_CONDITIONAL to
2948  * flag that we must later determine if we can use bulk-inserts for
2949  * the partition being inserted into.
2950  */
2951  if (proute)
2952  insertMethod = CIM_MULTI_CONDITIONAL;
2953  else
2954  insertMethod = CIM_MULTI;
2955 
2956  CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate,
2957  estate, mycid, ti_options);
2958  }
2959 
2960  /*
2961  * If not using batch mode (which allocates slots as needed) set up a
2962  * tuple slot too. When inserting into a partitioned table, we also need
2963  * one, even if we might batch insert, to read the tuple in the root
2964  * partition's form.
2965  */
2966  if (insertMethod == CIM_SINGLE || insertMethod == CIM_MULTI_CONDITIONAL)
2967  {
2968  singleslot = table_slot_create(resultRelInfo->ri_RelationDesc,
2969  &estate->es_tupleTable);
2970  bistate = GetBulkInsertState();
2971  }
2972 
2973  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
2974  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
2975 
2976  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
2977  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
2978 
2979  /*
2980  * Check BEFORE STATEMENT insertion triggers. It's debatable whether we
2981  * should do this for COPY, since it's not really an "INSERT" statement as
2982  * such. However, executing these triggers maintains consistency with the
2983  * EACH ROW triggers that we already fire on COPY.
2984  */
2985  ExecBSInsertTriggers(estate, resultRelInfo);
2986 
2987  econtext = GetPerTupleExprContext(estate);
2988 
2989  /* Set up callback to identify error line number */
2990  errcallback.callback = CopyFromErrorCallback;
2991  errcallback.arg = (void *) cstate;
2992  errcallback.previous = error_context_stack;
2993  error_context_stack = &errcallback;
2994 
2995  for (;;)
2996  {
2997  TupleTableSlot *myslot;
2998  bool skip_tuple;
2999 
3001 
3002  /*
3003  * Reset the per-tuple exprcontext. We do this after every tuple, to
3004  * clean-up after expression evaluations etc.
3005  */
3006  ResetPerTupleExprContext(estate);
3007 
3008  /* select slot to (initially) load row into */
3009  if (insertMethod == CIM_SINGLE || proute)
3010  {
3011  myslot = singleslot;
3012  Assert(myslot != NULL);
3013  }
3014  else
3015  {
3016  Assert(resultRelInfo == target_resultRelInfo);
3017  Assert(insertMethod == CIM_MULTI);
3018 
3019  myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
3020  resultRelInfo);
3021  }
3022 
3023  /*
3024  * Switch to per-tuple context before calling NextCopyFrom, which does
3025  * evaluate default expressions etc. and requires per-tuple context.
3026  */
3028 
3029  ExecClearTuple(myslot);
3030 
3031  /* Directly store the values/nulls array in the slot */
3032  if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
3033  break;
3034 
3035  ExecStoreVirtualTuple(myslot);
3036 
3037  /*
3038  * Constraints and where clause might reference the tableoid column,
3039  * so (re-)initialize tts_tableOid before evaluating them.
3040  */
3041  myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
3042 
3043  /* Triggers and stuff need to be invoked in query context. */
3044  MemoryContextSwitchTo(oldcontext);
3045 
3046  if (cstate->whereClause)
3047  {
3048  econtext->ecxt_scantuple = myslot;
3049  /* Skip items that don't match COPY's WHERE clause */
3050  if (!ExecQual(cstate->qualexpr, econtext))
3051  continue;
3052  }
3053 
3054  /* Determine the partition to insert the tuple into */
3055  if (proute)
3056  {
3057  TupleConversionMap *map;
3058 
3059  /*
3060  * Attempt to find a partition suitable for this tuple.
3061  * ExecFindPartition() will raise an error if none can be found or
3062  * if the found partition is not suitable for INSERTs.
3063  */
3064  resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
3065  proute, myslot, estate);
3066 
3067  if (prevResultRelInfo != resultRelInfo)
3068  {
3069  /* Determine which triggers exist on this partition */
3070  has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
3071  resultRelInfo->ri_TrigDesc->trig_insert_before_row);
3072 
3073  has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
3074  resultRelInfo->ri_TrigDesc->trig_insert_instead_row);
3075 
3076  /*
3077  * Disable multi-inserts when the partition has BEFORE/INSTEAD
3078  * OF triggers, or if the partition is a foreign partition.
3079  */
3080  leafpart_use_multi_insert = insertMethod == CIM_MULTI_CONDITIONAL &&
3081  !has_before_insert_row_trig &&
3082  !has_instead_insert_row_trig &&
3083  resultRelInfo->ri_FdwRoutine == NULL;
3084 
3085  /* Set the multi-insert buffer to use for this partition. */
3086  if (leafpart_use_multi_insert)
3087  {
3088  if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL)
3089  CopyMultiInsertInfoSetupBuffer(&multiInsertInfo,
3090  resultRelInfo);
3091  }
3092  else if (insertMethod == CIM_MULTI_CONDITIONAL &&
3093  !CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
3094  {
3095  /*
3096  * Flush pending inserts if this partition can't use
3097  * batching, so rows are visible to triggers etc.
3098  */
3099  CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo);
3100  }
3101 
3102  if (bistate != NULL)
3103  ReleaseBulkInsertStatePin(bistate);
3104  prevResultRelInfo = resultRelInfo;
3105  }
3106 
3107  /*
3108  * If we're capturing transition tuples, we might need to convert
3109  * from the partition rowtype to root rowtype. But if there are no
3110  * BEFORE triggers on the partition that could change the tuple,
3111  * we can just remember the original unconverted tuple to avoid a
3112  * needless round trip conversion.
3113  */
3114  if (cstate->transition_capture != NULL)
3116  !has_before_insert_row_trig ? myslot : NULL;
3117 
3118  /*
3119  * We might need to convert from the root rowtype to the partition
3120  * rowtype.
3121  */
3122  map = resultRelInfo->ri_RootToPartitionMap;
3123  if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert)
3124  {
3125  /* non batch insert */
3126  if (map != NULL)
3127  {
3128  TupleTableSlot *new_slot;
3129 
3130  new_slot = resultRelInfo->ri_PartitionTupleSlot;
3131  myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
3132  }
3133  }
3134  else
3135  {
3136  /*
3137  * Prepare to queue up tuple for later batch insert into
3138  * current partition.
3139  */
3140  TupleTableSlot *batchslot;
3141 
3142  /* no other path available for partitioned table */
3143  Assert(insertMethod == CIM_MULTI_CONDITIONAL);
3144 
3145  batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo,
3146  resultRelInfo);
3147 
3148  if (map != NULL)
3149  myslot = execute_attr_map_slot(map->attrMap, myslot,
3150  batchslot);
3151  else
3152  {
3153  /*
3154  * This looks more expensive than it is (Believe me, I
3155  * optimized it away. Twice.). The input is in virtual
3156  * form, and we'll materialize the slot below - for most
3157  * slot types the copy performs the work materialization
3158  * would later require anyway.
3159  */
3160  ExecCopySlot(batchslot, myslot);
3161  myslot = batchslot;
3162  }
3163  }
3164 
3165  /* ensure that triggers etc see the right relation */
3166  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
3167  }
3168 
3169  skip_tuple = false;
3170 
3171  /* BEFORE ROW INSERT Triggers */
3172  if (has_before_insert_row_trig)
3173  {
3174  if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot))
3175  skip_tuple = true; /* "do nothing" */
3176  }
3177 
3178  if (!skip_tuple)
3179  {
3180  /*
3181  * If there is an INSTEAD OF INSERT ROW trigger, let it handle the
3182  * tuple. Otherwise, proceed with inserting the tuple into the
3183  * table or foreign table.
3184  */
3185  if (has_instead_insert_row_trig)
3186  {
3187  ExecIRInsertTriggers(estate, resultRelInfo, myslot);
3188  }
3189  else
3190  {
3191  /* Compute stored generated columns */
3192  if (resultRelInfo->ri_RelationDesc->rd_att->constr &&
3194  ExecComputeStoredGenerated(resultRelInfo, estate, myslot,
3195  CMD_INSERT);
3196 
3197  /*
3198  * If the target is a plain table, check the constraints of
3199  * the tuple.
3200  */
3201  if (resultRelInfo->ri_FdwRoutine == NULL &&
3202  resultRelInfo->ri_RelationDesc->rd_att->constr)
3203  ExecConstraints(resultRelInfo, myslot, estate);
3204 
3205  /*
3206  * Also check the tuple against the partition constraint, if
3207  * there is one; except that if we got here via tuple-routing,
3208  * we don't need to if there's no BR trigger defined on the
3209  * partition.
3210  */
3211  if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition &&
3212  (proute == NULL || has_before_insert_row_trig))
3213  ExecPartitionCheck(resultRelInfo, myslot, estate, true);
3214 
3215  /* Store the slot in the multi-insert buffer, when enabled. */
3216  if (insertMethod == CIM_MULTI || leafpart_use_multi_insert)
3217  {
3218  /*
3219  * The slot previously might point into the per-tuple
3220  * context. For batching it needs to be longer lived.
3221  */
3222  ExecMaterializeSlot(myslot);
3223 
3224  /* Add this tuple to the tuple buffer */
3225  CopyMultiInsertInfoStore(&multiInsertInfo,
3226  resultRelInfo, myslot,
3227  cstate->line_buf.len,
3228  cstate->cur_lineno);
3229 
3230  /*
3231  * If enough inserts have queued up, then flush all
3232  * buffers out to their tables.
3233  */
3234  if (CopyMultiInsertInfoIsFull(&multiInsertInfo))
3235  CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo);
3236  }
3237  else
3238  {
3239  List *recheckIndexes = NIL;
3240 
3241  /* OK, store the tuple */
3242  if (resultRelInfo->ri_FdwRoutine != NULL)
3243  {
3244  myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
3245  resultRelInfo,
3246  myslot,
3247  NULL);
3248 
3249  if (myslot == NULL) /* "do nothing" */
3250  continue; /* next tuple please */
3251 
3252  /*
3253  * AFTER ROW Triggers might reference the tableoid
3254  * column, so (re-)initialize tts_tableOid before
3255  * evaluating them.
3256  */
3257  myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
3258  }
3259  else
3260  {
3261  /* OK, store the tuple and create index entries for it */
3262  table_tuple_insert(resultRelInfo->ri_RelationDesc,
3263  myslot, mycid, ti_options, bistate);
3264 
3265  if (resultRelInfo->ri_NumIndices > 0)
3266  recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
3267  myslot,
3268  estate,
3269  false,
3270  NULL,
3271  NIL);
3272  }
3273 
3274  /* AFTER ROW INSERT Triggers */
3275  ExecARInsertTriggers(estate, resultRelInfo, myslot,
3276  recheckIndexes, cstate->transition_capture);
3277 
3278  list_free(recheckIndexes);
3279  }
3280  }
3281 
3282  /*
3283  * We count only tuples not suppressed by a BEFORE INSERT trigger
3284  * or FDW; this is the same definition used by nodeModifyTable.c
3285  * for counting tuples inserted by an INSERT command.
3286  */
3287  processed++;
3288  }
3289  }
3290 
3291  /* Flush any remaining buffered tuples */
3292  if (insertMethod != CIM_SINGLE)
3293  {
3294  if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
3295  CopyMultiInsertInfoFlush(&multiInsertInfo, NULL);
3296  }
3297 
3298  /* Done, clean up */
3299  error_context_stack = errcallback.previous;
3300 
3301  if (bistate != NULL)
3302  FreeBulkInsertState(bistate);
3303 
3304  MemoryContextSwitchTo(oldcontext);
3305 
3306  /*
3307  * In the old protocol, tell pqcomm that we can process normal protocol
3308  * messages again.
3309  */
3310  if (cstate->copy_dest == COPY_OLD_FE)
3311  pq_endmsgread();
3312 
3313  /* Execute AFTER STATEMENT insertion triggers */
3314  ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture);
3315 
3316  /* Handle queued AFTER triggers */
3317  AfterTriggerEndQuery(estate);
3318 
3319  ExecResetTupleTable(estate->es_tupleTable, false);
3320 
3321  /* Allow the FDW to shut down */
3322  if (target_resultRelInfo->ri_FdwRoutine != NULL &&
3323  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
3324  target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate,
3325  target_resultRelInfo);
3326 
3327  /* Tear down the multi-insert buffer data */
3328  if (insertMethod != CIM_SINGLE)
3329  CopyMultiInsertInfoCleanup(&multiInsertInfo);
3330 
3331  /* Close all the partitioned tables, leaf partitions, and their indices */
3332  if (proute)
3333  ExecCleanupTupleRouting(mtstate, proute);
3334 
3335  /* Close the result relations, including any trigger target relations */
3336  ExecCloseResultRelations(estate);
3338 
3339  FreeExecutorState(estate);
3340 
3341  return processed;
3342 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
int ri_NumIndices
Definition: execnodes.h:415
Node * whereClause
Definition: copy.c:156
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:535
void ExecInitRangeTable(EState *estate, List *rangeTable)
Definition: execUtils.c:750
Relation ri_RelationDesc
Definition: execnodes.h:412
List * range_table
Definition: copy.c:184
static void CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, TupleTableSlot *slot, int tuplen, uint64 lineno)
Definition: copy.c:2681
int errhint(const char *fmt,...)
Definition: elog.c:1068
void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture)
Definition: trigger.c:2248
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition: execnodes.h:502
void CopyFromErrorCallback(void *arg)
Definition: copy.c:2288
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
#define ResetPerTupleExprContext(estate)
Definition: executor.h:515
#define TABLE_INSERT_FROZEN
Definition: tableam.h:134
#define castNode(_type_, nodeptr)
Definition: nodes.h:597
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition: execUtils.c:833
BeginForeignInsert_function BeginForeignInsert
Definition: fdwapi.h:215
ResultRelInfo * resultRelInfo
Definition: execnodes.h:1168
void ExecCloseResultRelations(EState *estate)
Definition: execMain.c:1430
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:211
static void CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copy.c:2411
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1801
StringInfoData line_buf
Definition: copy.c:215
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition: snapmgr.c:1604
int errcode(int sqlerrcode)
Definition: elog.c:610
void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, CmdType cmdtype)
CmdType operation
Definition: execnodes.h:1160
SubTransactionId rd_newRelfilenodeSubid
Definition: rel.h:103
Datum * tts_values
Definition: tuptable.h:126
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:724
EState * state
Definition: execnodes.h:941
Form_pg_class rd_rel
Definition: rel.h:109
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:369
bool volatile_defexprs
Definition: copy.c:183
void(* callback)(void *arg)
Definition: elog.h:229
struct ErrorContextCallback * previous
Definition: elog.h:228
static void CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, CopyState cstate, EState *estate, CommandId mycid, int ti_options)
Definition: copy.c:2431
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:1178
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:209
void ExecCloseRangeTableRelations(EState *estate)
Definition: execMain.c:1473
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:151
CopyDest copy_dest
Definition: copy.c:117
ErrorContextCallback * error_context_stack
Definition: elog.c:92
uint64 cur_lineno
Definition: copy.c:160
bool trig_insert_instead_row
Definition: reltrigger.h:58
void FreeExecutorState(EState *estate)
Definition: execUtils.c:185
Relation rel
Definition: copy.c:130
#define GetPerTupleExprContext(estate)
Definition: executor.h:506
BulkInsertState GetBulkInsertState(void)
Definition: heapam.c:1806
bool trig_insert_new_table
Definition: reltrigger.h:75
bool has_generated_stored
Definition: tupdesc.h:45
bool ThereAreNoReadyPortals(void)
Definition: portalmem.c:1209
#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:2172
static bool CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2456
static bool CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2468
List * ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes)
Definition: execIndexing.c:273
TupleTableSlot * ri_PartitionTupleSlot
Definition: execnodes.h:492
TriggerDesc * trigdesc
Definition: rel.h:115
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
Definition: execMain.c:995
void ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
Definition: trigger.c:2110
struct TransitionCaptureState * mt_transition_capture
Definition: execnodes.h:1190
bool * tts_isnull
Definition: tuptable.h:128
static void CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri)
Definition: copy.c:2597
TupleConstr * constr
Definition: tupdesc.h:85
#define RelationGetRelationName(relation)
Definition: rel.h:490
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:441
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, Relation rel)
AttrMap * attrMap
Definition: tupconvert.h:27
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:456
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:424
EState * CreateExecutorState(void)
Definition: execUtils.c:89
SubTransactionId rd_createSubid
Definition: rel.h:102
Definition: copy.c:94
bool trig_insert_before_row
Definition: reltrigger.h:56
SubTransactionId rd_firstRelfilenodeSubid
Definition: rel.h:105
List * es_tupleTable
Definition: execnodes.h:561
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1161
void ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture)
Definition: trigger.c:2161
TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
Definition: trigger.c:4291
#define TABLE_INSERT_SKIP_FSM
Definition: tableam.h:133
TupleDesc rd_att
Definition: rel.h:110
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:443
bool freeze
Definition: copy.c:137
Plan * plan
Definition: execnodes.h:939
void pq_endmsgread(void)
Definition: pqcomm.c:1221
#define ereport(elevel,...)
Definition: elog.h:144
void AfterTriggerBeginQuery(void)
Definition: trigger.c:4413
#define makeNode(_type_)
Definition: nodes.h:576
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:177
#define Assert(condition)
Definition: c.h:746
void FreeBulkInsertState(BulkInsertState bistate)
Definition: heapam.c:1820
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot)
Definition: trigger.c:2263
CopyInsertMethod
Definition: copy.c:91
bool NextCopyFrom(CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls)
Definition: copy.c:3663
static TupleTableSlot * CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri)
Definition: copy.c:2662
static int list_length(const List *l)
Definition: pg_list.h:149
static void CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
Definition: copy.c:2643
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:225
#define InvalidSubTransactionId
Definition: c.h:527
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
Definition: heapam.c:1832
#define GetPerTupleMemoryContext(estate)
Definition: executor.h:511
void AfterTriggerEndQuery(EState *estate)
Definition: trigger.c:4433
TupleConversionMap * ri_RootToPartitionMap
Definition: execnodes.h:491
int errmsg(const char *fmt,...)
Definition: elog.c:821
void list_free(List *list)
Definition: list.c:1376
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition: execMain.c:1679
TransitionCaptureState * transition_capture
Definition: copy.c:187
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:761
ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:456
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522
EndForeignInsert_function EndForeignInsert
Definition: fdwapi.h:216
TupleTableSlot * tcs_original_insert_tuple
Definition: trigger.h:75
ExprState * qualexpr
Definition: copy.c:185

◆ CopyFromErrorCallback()

void CopyFromErrorCallback ( void *  arg)

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

2289 {
2290  CopyState cstate = (CopyState) arg;
2291  char curlineno_str[32];
2292 
2293  snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT,
2294  cstate->cur_lineno);
2295 
2296  if (cstate->binary)
2297  {
2298  /* can't usefully display the data */
2299  if (cstate->cur_attname)
2300  errcontext("COPY %s, line %s, column %s",
2301  cstate->cur_relname, curlineno_str,
2302  cstate->cur_attname);
2303  else
2304  errcontext("COPY %s, line %s",
2305  cstate->cur_relname, curlineno_str);
2306  }
2307  else
2308  {
2309  if (cstate->cur_attname && cstate->cur_attval)
2310  {
2311  /* error is relevant to a particular column */
2312  char *attval;
2313 
2314  attval = limit_printout_length(cstate->cur_attval);
2315  errcontext("COPY %s, line %s, column %s: \"%s\"",
2316  cstate->cur_relname, curlineno_str,
2317  cstate->cur_attname, attval);
2318  pfree(attval);
2319  }
2320  else if (cstate->cur_attname)
2321  {
2322  /* error is relevant to a particular column, value is NULL */
2323  errcontext("COPY %s, line %s, column %s: null input",
2324  cstate->cur_relname, curlineno_str,
2325  cstate->cur_attname);
2326  }
2327  else
2328  {
2329  /*
2330  * Error is relevant to a particular line.
2331  *
2332  * If line_buf still contains the correct line, and it's already
2333  * transcoded, print it. If it's still in a foreign encoding, it's
2334  * quite likely that the error is precisely a failure to do
2335  * encoding conversion (ie, bad data). We dare not try to convert
2336  * it, and at present there's no way to regurgitate it without
2337  * conversion. So we have to punt and just report the line number.
2338  */
2339  if (cstate->line_buf_valid &&
2340  (cstate->line_buf_converted || !cstate->need_transcoding))
2341  {
2342  char *lineval;
2343 
2344  lineval = limit_printout_length(cstate->line_buf.data);
2345  errcontext("COPY %s, line %s: \"%s\"",
2346  cstate->cur_relname, curlineno_str, lineval);
2347  pfree(lineval);
2348  }
2349  else
2350  {
2351  errcontext("COPY %s, line %s",
2352  cstate->cur_relname, curlineno_str);
2353  }
2354  }
2355  }
2356 }
bool binary
Definition: copy.c:136
bool need_transcoding
Definition: copy.c:126
StringInfoData line_buf
Definition: copy.c:215
bool line_buf_valid
Definition: copy.c:217
bool line_buf_converted
Definition: copy.c:216
uint64 cur_lineno
Definition: copy.c:160
const char * cur_attname
Definition: copy.c:161
void pfree(void *pointer)
Definition: mcxt.c:1057
static char * limit_printout_length(const char *str)
Definition: copy.c:2364
const char * cur_relname
Definition: copy.c:159
#define errcontext
Definition: elog.h:185
struct CopyStateData * CopyState
Definition: copy.h:23
void * arg
const char * cur_attval
Definition: copy.c:162
#define snprintf
Definition: port.h:215
#define UINT64_FORMAT
Definition: c.h:418

◆ CreateCopyDestReceiver()

DestReceiver* CreateCopyDestReceiver ( void  )

Definition at line 5173 of file copy.c.

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

Referenced by CreateDestReceiver().

5174 {
5175  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
5176 
5177  self->pub.receiveSlot = copy_dest_receive;
5178  self->pub.rStartup = copy_dest_startup;
5179  self->pub.rShutdown = copy_dest_shutdown;
5180  self->pub.rDestroy = copy_dest_destroy;
5181  self->pub.mydest = DestCopyOut;
5182 
5183  self->cstate = NULL; /* will be set later */
5184  self->processed = 0;
5185 
5186  return (DestReceiver *) self;
5187 }
Definition: copy.c:236
static void copy_dest_destroy(DestReceiver *self)
Definition: copy.c:5164
static void copy_dest_shutdown(DestReceiver *self)
Definition: copy.c:5155
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copy.c:5130
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copy.c:5139
void * palloc(Size size)
Definition: mcxt.c:950

◆ DoCopy()

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

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

891 {
892  CopyState cstate;
893  bool is_from = stmt->is_from;
894  bool pipe = (stmt->filename == NULL);
895  Relation rel;
896  Oid relid;
897  RawStmt *query = NULL;
898  Node *whereClause = NULL;
899 
900  /*
901  * Disallow COPY to/from file or program except to users with the
902  * appropriate role.
903  */
904  if (!pipe)
905  {
906  if (stmt->is_program)
907  {
908  if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_EXECUTE_SERVER_PROGRAM))
909  ereport(ERROR,
910  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
911  errmsg("must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program"),
912  errhint("Anyone can COPY to stdout or from stdin. "
913  "psql's \\copy command also works for anyone.")));
914  }
915  else
916  {
917  if (is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES))
918  ereport(ERROR,
919  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
920  errmsg("must be superuser or a member of the pg_read_server_files role to COPY from a file"),
921  errhint("Anyone can COPY to stdout or from stdin. "
922  "psql's \\copy command also works for anyone.")));
923 
924  if (!is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_WRITE_SERVER_FILES))
925  ereport(ERROR,
926  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
927  errmsg("must be superuser or a member of the pg_write_server_files role to COPY to a file"),
928  errhint("Anyone can COPY to stdout or from stdin. "
929  "psql's \\copy command also works for anyone.")));
930  }
931  }
932 
933  if (stmt->relation)
934  {
935  LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
936  ParseNamespaceItem *nsitem;
937  RangeTblEntry *rte;
938  TupleDesc tupDesc;
939  List *attnums;
940  ListCell *cur;
941 
942  Assert(!stmt->query);
943 
944  /* Open and lock the relation, using the appropriate lock type. */
945  rel = table_openrv(stmt->relation, lockmode);
946 
947  relid = RelationGetRelid(rel);
948 
949  nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
950  NULL, false, false);
951  rte = nsitem->p_rte;
952  rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
953 
954  if (stmt->whereClause)
955  {
956  /* add nsitem to query namespace */
957  addNSItemToQuery(pstate, nsitem, false, true, true);
958 
959  /* Transform the raw expression tree */
960  whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
961 
962  /* Make sure it yields a boolean result. */
963  whereClause = coerce_to_boolean(pstate, whereClause, "WHERE");
964 
965  /* we have to fix its collations too */
966  assign_expr_collations(pstate, whereClause);
967 
968  whereClause = eval_const_expressions(NULL, whereClause);
969 
970  whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
971  whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
972  }
973 
974  tupDesc = RelationGetDescr(rel);
975  attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
976  foreach(cur, attnums)
977  {
978  int attno = lfirst_int(cur) -
980 
981  if (is_from)
982  rte->insertedCols = bms_add_member(rte->insertedCols, attno);
983  else
984  rte->selectedCols = bms_add_member(rte->selectedCols, attno);
985  }
986  ExecCheckRTPerms(pstate->p_rtable, true);
987 
988  /*
989  * Permission check for row security policies.
990  *
991  * check_enable_rls will ereport(ERROR) if the user has requested
992  * something invalid and will otherwise indicate if we should enable
993  * RLS (returns RLS_ENABLED) or not for this COPY statement.
994  *
995  * If the relation has a row security policy and we are to apply it
996  * then perform a "query" copy and allow the normal query processing
997  * to handle the policies.
998  *
999  * If RLS is not enabled for this, then just fall through to the
1000  * normal non-filtering relation handling.
1001  */
1002  if (check_enable_rls(rte->relid, InvalidOid, false) == RLS_ENABLED)
1003  {
1004  SelectStmt *select;
1005  ColumnRef *cr;
1006  ResTarget *target;
1007  RangeVar *from;
1008  List *targetList = NIL;
1009 
1010  if (is_from)
1011  ereport(ERROR,
1012  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1013  errmsg("COPY FROM not supported with row-level security"),
1014  errhint("Use INSERT statements instead.")));
1015 
1016  /*
1017  * Build target list
1018  *
1019  * If no columns are specified in the attribute list of the COPY
1020  * command, then the target list is 'all' columns. Therefore, '*'
1021  * should be used as the target list for the resulting SELECT
1022  * statement.
1023  *
1024  * In the case that columns are specified in the attribute list,
1025  * create a ColumnRef and ResTarget for each column and add them
1026  * to the target list for the resulting SELECT statement.
1027  */
1028  if (!stmt->attlist)
1029  {
1030  cr = makeNode(ColumnRef);
1031  cr->fields = list_make1(makeNode(A_Star));
1032  cr->location = -1;
1033 
1034  target = makeNode(ResTarget);
1035  target->name = NULL;
1036  target->indirection = NIL;
1037  target->val = (Node *) cr;
1038  target->location = -1;
1039 
1040  targetList = list_make1(target);
1041  }
1042  else
1043  {
1044  ListCell *lc;
1045 
1046  foreach(lc, stmt->attlist)
1047  {
1048  /*
1049  * Build the ColumnRef for each column. The ColumnRef
1050  * 'fields' property is a String 'Value' node (see
1051  * nodes/value.h) that corresponds to the column name
1052  * respectively.
1053  */
1054  cr = makeNode(ColumnRef);
1055  cr->fields = list_make1(lfirst(lc));
1056  cr->location = -1;
1057 
1058  /* Build the ResTarget and add the ColumnRef to it. */
1059  target = makeNode(ResTarget);
1060  target->name = NULL;
1061  target->indirection = NIL;
1062  target->val = (Node *) cr;
1063  target->location = -1;
1064 
1065  /* Add each column to the SELECT statement's target list */
1066  targetList = lappend(targetList, target);
1067  }
1068  }
1069 
1070  /*
1071  * Build RangeVar for from clause, fully qualified based on the
1072  * relation which we have opened and locked.
1073  */
1076  -1);
1077 
1078  /* Build query */
1079  select = makeNode(SelectStmt);
1080  select->targetList = targetList;
1081  select->fromClause = list_make1(from);
1082 
1083  query = makeNode(RawStmt);
1084  query->stmt = (Node *) select;
1085  query->stmt_location = stmt_location;
1086  query->stmt_len = stmt_len;
1087 
1088  /*
1089  * Close the relation for now, but keep the lock on it to prevent
1090  * changes between now and when we start the query-based COPY.
1091  *
1092  * We'll reopen it later as part of the query-based COPY.
1093  */
1094  table_close(rel, NoLock);
1095  rel = NULL;
1096  }
1097  }
1098  else
1099  {
1100  Assert(stmt->query);
1101 
1102  query = makeNode(RawStmt);
1103  query->stmt = stmt->query;
1104  query->stmt_location = stmt_location;
1105  query->stmt_len = stmt_len;
1106 
1107  relid = InvalidOid;
1108  rel = NULL;
1109  }
1110 
1111  if (is_from)
1112  {
1113  Assert(rel);
1114 
1115  /* check read-only transaction and parallel mode */
1116  if (XactReadOnly && !rel->rd_islocaltemp)
1117  PreventCommandIfReadOnly("COPY FROM");
1118 
1119  cstate = BeginCopyFrom(pstate, rel, stmt->filename, stmt->is_program,
1120  NULL, stmt->attlist, stmt->options);
1121  cstate->whereClause = whereClause;
1122  *processed = CopyFrom(cstate); /* copy from file to database */
1123  EndCopyFrom(cstate);
1124  }
1125  else
1126  {
1127  cstate = BeginCopyTo(pstate, rel, query, relid,
1128  stmt->filename, stmt->is_program,
1129  stmt->attlist, stmt->options);
1130  *processed = DoCopyTo(cstate); /* copy from database to file */
1131  EndCopyTo(cstate);
1132  }
1133 
1134  if (rel != NULL)
1135  table_close(rel, NoLock);
1136 }
List * indirection
Definition: parsenodes.h:443
Node * whereClause
Definition: copy.c:156
#define NIL
Definition: pg_list.h:65
Node * whereClause
Definition: parsenodes.h:2021
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Node * val
Definition: parsenodes.h:444
int errhint(const char *fmt,...)
Definition: elog.c:1068
List * attlist
Definition: parsenodes.h:2015
List * fromClause
Definition: parsenodes.h:1599
#define RelationGetDescr(relation)
Definition: rel.h:482
int LOCKMODE
Definition: lockdefs.h:26
char * name
Definition: parsenodes.h:442
Oid GetUserId(void)
Definition: miscinit.c:476
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:3355
char * pstrdup(const char *in)
Definition: mcxt.c:1187
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:528
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:610
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2287
uint64 CopyFrom(CopyState cstate)
Definition: copy.c:2704
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
AclMode requiredPerms
Definition: parsenodes.h:1120
unsigned int Oid
Definition: postgres_ext.h:31
bool is_program
Definition: parsenodes.h:2018
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
int location
Definition: parsenodes.h:237
int location
Definition: parsenodes.h:445
#define list_make1(x1)
Definition: pg_list.h:206
void assign_expr_collations(ParseState *pstate, Node *expr)
RangeTblEntry * p_rte
Definition: parse_node.h:257
Bitmapset * selectedCols
Definition: parsenodes.h:1122
static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, Oid queryRelId, const char *filename, bool is_program, List *attnamelist, List *options)
Definition: copy.c:1876
#define ERROR
Definition: elog.h:43
#define lfirst_int(lc)
Definition: pg_list.h:170
RangeVar * relation
Definition: parsenodes.h:2012
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
Node * stmt
Definition: parsenodes.h:1509
#define NoLock
Definition: lockdefs.h:34
List * targetList
Definition: parsenodes.h:1598
static uint64 DoCopyTo(CopyState cstate)
Definition: copy.c:2012
#define RowExclusiveLock
Definition: lockdefs.h:38
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:292
List * options
Definition: parsenodes.h:2020
#define select(n, r, w, e, timeout)
Definition: win32_port.h:464
#define RelationGetRelationName(relation)
Definition: rel.h:490
List * lappend(List *list, void *datum)
Definition: list.c:321
static List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
Definition: copy.c:5049
#define ACL_SELECT
Definition: parsenodes.h:75
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:718
int stmt_len
Definition: parsenodes.h:1511
int stmt_location
Definition: parsenodes.h:1510
Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: table.c:102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
bool XactReadOnly
Definition: xact.c:78
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4916
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition: rls.c:52
void EndCopyFrom(CopyState cstate)
Definition: copy.c:3848
#define makeNode(_type_)
Definition: nodes.h:576
#define Assert(condition)
Definition: c.h:746
#define lfirst(lc)
Definition: pg_list.h:169
#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:407
Node * query
Definition: parsenodes.h:2013
bool is_from
Definition: parsenodes.h:2017
int errmsg(const char *fmt,...)
Definition: elog.c:821
Bitmapset * insertedCols
Definition: parsenodes.h:1123
bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation)
Definition: execMain.c:571
char * filename
Definition: parsenodes.h:2019
static void EndCopyTo(CopyState cstate)
Definition: copy.c:2047
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:456
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
List * fields
Definition: parsenodes.h:236
#define RelationGetNamespace(relation)
Definition: rel.h:497
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)

◆ EndCopyFrom()

void EndCopyFrom ( CopyState  cstate)

Definition at line 3848 of file copy.c.

References EndCopy().

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

3849 {
3850  /* No COPY FROM related resources except memory. */
3851 
3852  EndCopy(cstate);
3853 }
static void EndCopy(CopyState cstate)
Definition: copy.c:1853

◆ NextCopyFrom()

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

Definition at line 3663 of file copy.c.

References Assert, attnum, CopyStateData::attnumlist, CopyStateData::binary, CopyStateData::convert_select_flags, CopyStateData::copy_dest, COPY_OLD_FE, CopyGetInt16(), CopyReadBinaryAttribute(), CopyReadBinaryData(), 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().

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

◆ NextCopyFromRawFields()

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

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

3612 {
3613  int fldct;
3614  bool done;
3615 
3616  /* only available for text or csv input */
3617  Assert(!cstate->binary);
3618 
3619  /* on input just throw the header line away */
3620  if (cstate->cur_lineno == 0 && cstate->header_line)
3621  {
3622  cstate->cur_lineno++;
3623  if (CopyReadLine(cstate))
3624  return false; /* done */
3625  }
3626 
3627  cstate->cur_lineno++;
3628 
3629  /* Actually read the line into memory here */
3630  done = CopyReadLine(cstate);
3631 
3632  /*
3633  * EOF at start of line means we're done. If we see EOF after some
3634  * characters, we act as though it was newline followed by EOF, ie,
3635  * process the line and then exit loop on next iteration.
3636  */
3637  if (done && cstate->line_buf.len == 0)
3638  return false;
3639 
3640  /* Parse the line into de-escaped field values */
3641  if (cstate->csv_mode)
3642  fldct = CopyReadAttributesCSV(cstate);
3643  else
3644  fldct = CopyReadAttributesText(cstate);
3645 
3646  *fields = cstate->raw_fields;
3647  *nfields = fldct;
3648  return true;
3649 }
bool csv_mode
Definition: copy.c:138
char ** raw_fields
Definition: copy.c:205
bool binary
Definition: copy.c:136
StringInfoData line_buf
Definition: copy.c:215
static int CopyReadAttributesCSV(CopyState cstate)
Definition: copy.c:4573
uint64 cur_lineno
Definition: copy.c:160
bool header_line
Definition: copy.c:139
#define Assert(condition)
Definition: c.h:746
static bool CopyReadLine(CopyState cstate)
Definition: copy.c:3864
static int CopyReadAttributesText(CopyState cstate)
Definition: copy.c:4345

◆ ProcessCopyOptions()

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

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

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