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 3334 of file copy.c.

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

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

3341 {
3342  CopyState cstate;
3343  bool pipe = (filename == NULL);
3344  TupleDesc tupDesc;
3345  AttrNumber num_phys_attrs,
3346  num_defaults;
3347  FmgrInfo *in_functions;
3348  Oid *typioparams;
3349  int attnum;
3350  Oid in_func_oid;
3351  int *defmap;
3352  ExprState **defexprs;
3353  MemoryContext oldcontext;
3354  bool volatile_defexprs;
3355 
3356  cstate = BeginCopy(pstate, true, rel, NULL, InvalidOid, attnamelist, options);
3357  oldcontext = MemoryContextSwitchTo(cstate->copycontext);
3358 
3359  /* Initialize state variables */
3360  cstate->reached_eof = false;
3361  cstate->eol_type = EOL_UNKNOWN;
3362  cstate->cur_relname = RelationGetRelationName(cstate->rel);
3363  cstate->cur_lineno = 0;
3364  cstate->cur_attname = NULL;
3365  cstate->cur_attval = NULL;
3366 
3367  /* Set up variables to avoid per-attribute overhead. */
3368  initStringInfo(&cstate->attribute_buf);
3369  initStringInfo(&cstate->line_buf);
3370  cstate->line_buf_converted = false;
3371  cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
3372  cstate->raw_buf_index = cstate->raw_buf_len = 0;
3373 
3374  /* Assign range table, we'll need it in CopyFrom. */
3375  if (pstate)
3376  cstate->range_table = pstate->p_rtable;
3377 
3378  tupDesc = RelationGetDescr(cstate->rel);
3379  num_phys_attrs = tupDesc->natts;
3380  num_defaults = 0;
3381  volatile_defexprs = false;
3382 
3383  /*
3384  * Pick up the required catalog information for each attribute in the
3385  * relation, including the input function, the element type (to pass to
3386  * the input function), and info about defaults and constraints. (Which
3387  * input function we use depends on text/binary format choice.)
3388  */
3389  in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
3390  typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
3391  defmap = (int *) palloc(num_phys_attrs * sizeof(int));
3392  defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
3393 
3394  for (attnum = 1; attnum <= num_phys_attrs; attnum++)
3395  {
3396  Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
3397 
3398  /* We don't need info for dropped attributes */
3399  if (att->attisdropped)
3400  continue;
3401 
3402  /* Fetch the input function and typioparam info */
3403  if (cstate->binary)
3404  getTypeBinaryInputInfo(att->atttypid,
3405  &in_func_oid, &typioparams[attnum - 1]);
3406  else
3407  getTypeInputInfo(att->atttypid,
3408  &in_func_oid, &typioparams[attnum - 1]);
3409  fmgr_info(in_func_oid, &in_functions[attnum - 1]);
3410 
3411  /* Get default info if needed */
3412  if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated)
3413  {
3414  /* attribute is NOT to be copied from input */
3415  /* use default value if one exists */
3416  Expr *defexpr = (Expr *) build_column_default(cstate->rel,
3417  attnum);
3418 
3419  if (defexpr != NULL)
3420  {
3421  /* Run the expression through planner */
3422  defexpr = expression_planner(defexpr);
3423 
3424  /* Initialize executable expression in copycontext */
3425  defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
3426  defmap[num_defaults] = attnum - 1;
3427  num_defaults++;
3428 
3429  /*
3430  * If a default expression looks at the table being loaded,
3431  * then it could give the wrong answer when using
3432  * multi-insert. Since database access can be dynamic this is
3433  * hard to test for exactly, so we use the much wider test of
3434  * whether the default expression is volatile. We allow for
3435  * the special case of when the default expression is the
3436  * nextval() of a sequence which in this specific case is
3437  * known to be safe for use with the multi-insert
3438  * optimization. Hence we use this special case function
3439  * checker rather than the standard check for
3440  * contain_volatile_functions().
3441  */
3442  if (!volatile_defexprs)
3443  volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr);
3444  }
3445  }
3446  }
3447 
3448  /* We keep those variables in cstate. */
3449  cstate->in_functions = in_functions;
3450  cstate->typioparams = typioparams;
3451  cstate->defmap = defmap;
3452  cstate->defexprs = defexprs;
3453  cstate->volatile_defexprs = volatile_defexprs;
3454  cstate->num_defaults = num_defaults;
3455  cstate->is_program = is_program;
3456 
3457  if (data_source_cb)
3458  {
3459  cstate->copy_dest = COPY_CALLBACK;
3460  cstate->data_source_cb = data_source_cb;
3461  }
3462  else if (pipe)
3463  {
3464  Assert(!is_program); /* the grammar does not allow this */
3466  ReceiveCopyBegin(cstate);
3467  else
3468  cstate->copy_file = stdin;
3469  }
3470  else
3471  {
3472  cstate->filename = pstrdup(filename);
3473 
3474  if (cstate->is_program)
3475  {
3476  cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R);
3477  if (cstate->copy_file == NULL)
3478  ereport(ERROR,
3480  errmsg("could not execute command \"%s\": %m",
3481  cstate->filename)));
3482  }
3483  else
3484  {
3485  struct stat st;
3486 
3487  cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R);
3488  if (cstate->copy_file == NULL)
3489  {
3490  /* copy errno because ereport subfunctions might change it */
3491  int save_errno = errno;
3492 
3493  ereport(ERROR,
3495  errmsg("could not open file \"%s\" for reading: %m",
3496  cstate->filename),
3497  (save_errno == ENOENT || save_errno == EACCES) ?
3498  errhint("COPY FROM instructs the PostgreSQL server process to read a file. "
3499  "You may want a client-side facility such as psql's \\copy.") : 0));
3500  }
3501 
3502  if (fstat(fileno(cstate->copy_file), &st))
3503  ereport(ERROR,
3505  errmsg("could not stat file \"%s\": %m",
3506  cstate->filename)));
3507 
3508  if (S_ISDIR(st.st_mode))
3509  ereport(ERROR,
3510  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3511  errmsg("\"%s\" is a directory", cstate->filename)));
3512  }
3513  }
3514 
3515  if (cstate->binary)
3516  {
3517  /* Read and verify binary header */
3518  char readSig[11];
3519  int32 tmp;
3520 
3521  /* Signature */
3522  if (CopyGetData(cstate, readSig, 11, 11) != 11 ||
3523  memcmp(readSig, BinarySignature, 11) != 0)
3524  ereport(ERROR,
3525  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3526  errmsg("COPY file signature not recognized")));
3527  /* Flags field */
3528  if (!CopyGetInt32(cstate, &tmp))
3529  ereport(ERROR,
3530  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3531  errmsg("invalid COPY file header (missing flags)")));
3532  if ((tmp & (1 << 16)) != 0)
3533  ereport(ERROR,
3534  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3535  errmsg("invalid COPY file header (WITH OIDS)")));
3536  tmp &= ~(1 << 16);
3537  if ((tmp >> 16) != 0)
3538  ereport(ERROR,
3539  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3540  errmsg("unrecognized critical flags in COPY file header")));
3541  /* Header extension length */
3542  if (!CopyGetInt32(cstate, &tmp) ||
3543  tmp < 0)
3544  ereport(ERROR,
3545  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3546  errmsg("invalid COPY file header (missing length)")));
3547  /* Skip extension header, if present */
3548  while (tmp-- > 0)
3549  {
3550  if (CopyGetData(cstate, readSig, 1, 1) != 1)
3551  ereport(ERROR,
3552  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3553  errmsg("invalid COPY file header (wrong length)")));
3554  }
3555  }
3556 
3557  /* create workspace for CopyReadAttributes results */
3558  if (!cstate->binary)
3559  {
3560  AttrNumber attr_count = list_length(cstate->attnumlist);
3561 
3562  cstate->max_fields = attr_count;
3563  cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
3564  }
3565 
3566  MemoryContextSwitchTo(oldcontext);
3567 
3568  return cstate;
3569 }
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:1457
bool contain_volatile_functions_not_nextval(Node *clause)
Definition: clauses.c:776
static bool CopyGetInt32(CopyState cstate, int32 *val)
Definition: copy.c:739
int errhint(const char *fmt,...)
Definition: elog.c:1071
char ** raw_fields
Definition: copy.c:202
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:1186
static void ReceiveCopyBegin(CopyState cstate)
Definition: copy.c:435
Expr * expression_planner(Expr *expr)
Definition: planner.c:6157
StringInfoData line_buf
Definition: copy.c:211
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:529
int raw_buf_index
Definition: copy.c:224
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:1236
bool line_buf_converted
Definition: copy.c:212
signed int int32
Definition: c.h:355
CopyDest copy_dest
Definition: copy.c:117
uint64 cur_lineno
Definition: copy.c:160
const char * cur_attname
Definition: copy.c:161
Relation rel
Definition: copy.c:130
MemoryContext copycontext
Definition: copy.c:167
copy_data_source_cb data_source_cb
Definition: copy.c:135
#define ERROR
Definition: elog.h:43
static int CopyGetData(CopyState cstate, void *databuf, int minread, int maxread)
Definition: copy.c:611
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
bool list_member_int(const List *list, int datum)
Definition: list.c:654
char * raw_buf
Definition: copy.c:223
ExprState ** defexprs
Definition: copy.c:182
const char * cur_relname
Definition: copy.c:159
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2320
#define RelationGetRelationName(relation)
Definition: rel.h:490
static const char BinarySignature[11]
Definition: copy.c:350
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
int raw_buf_len
Definition: copy.c:225
int max_fields
Definition: copy.c:201
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2423
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2768
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2702
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define stat(a, b)
Definition: win32_port.h:255
Oid * typioparams
Definition: copy.c:180
bool is_program
Definition: copy.c:134
Node * build_column_default(Relation rel, int attrno)
#define RAW_BUF_SIZE
Definition: copy.c:222
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:144
EolType eol_type
Definition: copy.c:124
#define Assert(condition)
Definition: c.h:738
bool reached_eof
Definition: copy.c:122
static int list_length(const List *l)
Definition: pg_list.h:169
#define S_ISDIR(m)
Definition: win32_port.h:296
static char * filename
Definition: pg_dumpall.c:90
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
FILE * copy_file
Definition: copy.c:118
StringInfoData attribute_buf
Definition: copy.c:197
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 2653 of file copy.c.

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

Referenced by copy_table(), and DoCopy().

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

◆ CopyFromErrorCallback()

void CopyFromErrorCallback ( void *  arg)

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

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

◆ CreateCopyDestReceiver()

DestReceiver* CreateCopyDestReceiver ( void  )

Definition at line 5149 of file copy.c.

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

Referenced by CreateDestReceiver().

5150 {
5151  DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy));
5152 
5153  self->pub.receiveSlot = copy_dest_receive;
5154  self->pub.rStartup = copy_dest_startup;
5155  self->pub.rShutdown = copy_dest_shutdown;
5156  self->pub.rDestroy = copy_dest_destroy;
5157  self->pub.mydest = DestCopyOut;
5158 
5159  self->cstate = NULL; /* will be set later */
5160  self->processed = 0;
5161 
5162  return (DestReceiver *) self;
5163 }
Definition: copy.c:229
static void copy_dest_destroy(DestReceiver *self)
Definition: copy.c:5140
static void copy_dest_shutdown(DestReceiver *self)
Definition: copy.c:5131
static void copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: copy.c:5106
static bool copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: copy.c:5115
void * palloc(Size size)
Definition: mcxt.c:949

◆ DoCopy()

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

Definition at line 838 of file copy.c.

References AccessShareLock, ACL_INSERT, ACL_SELECT, 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().

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

References EndCopy().

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

3824 {
3825  /* No COPY FROM related resources except memory. */
3826 
3827  EndCopy(cstate);
3828 }
static void EndCopy(CopyState cstate)
Definition: copy.c:1799

◆ NextCopyFrom()

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

Definition at line 3635 of file copy.c.

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

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

3637 {
3638  TupleDesc tupDesc;
3639  AttrNumber num_phys_attrs,
3640  attr_count,
3641  num_defaults = cstate->num_defaults;
3642  FmgrInfo *in_functions = cstate->in_functions;
3643  Oid *typioparams = cstate->typioparams;
3644  int i;
3645  int *defmap = cstate->defmap;
3646  ExprState **defexprs = cstate->defexprs;
3647 
3648  tupDesc = RelationGetDescr(cstate->rel);
3649  num_phys_attrs = tupDesc->natts;
3650  attr_count = list_length(cstate->attnumlist);
3651 
3652  /* Initialize all values for row to NULL */
3653  MemSet(values, 0, num_phys_attrs * sizeof(Datum));
3654  MemSet(nulls, true, num_phys_attrs * sizeof(bool));
3655 
3656  if (!cstate->binary)
3657  {
3658  char **field_strings;
3659  ListCell *cur;
3660  int fldct;
3661  int fieldno;
3662  char *string;
3663 
3664  /* read raw fields in the next line */
3665  if (!NextCopyFromRawFields(cstate, &field_strings, &fldct))
3666  return false;
3667 
3668  /* check for overflowing fields */
3669  if (attr_count > 0 && fldct > attr_count)
3670  ereport(ERROR,
3671  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3672  errmsg("extra data after last expected column")));
3673 
3674  fieldno = 0;
3675 
3676  /* Loop to read the user attributes on the line. */
3677  foreach(cur, cstate->attnumlist)
3678  {
3679  int attnum = lfirst_int(cur);
3680  int m = attnum - 1;
3681  Form_pg_attribute att = TupleDescAttr(tupDesc, m);
3682 
3683  if (fieldno >= fldct)
3684  ereport(ERROR,
3685  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3686  errmsg("missing data for column \"%s\"",
3687  NameStr(att->attname))));
3688  string = field_strings[fieldno++];
3689 
3690  if (cstate->convert_select_flags &&
3691  !cstate->convert_select_flags[m])
3692  {
3693  /* ignore input field, leaving column as NULL */
3694  continue;
3695  }
3696 
3697  if (cstate->csv_mode)
3698  {
3699  if (string == NULL &&
3700  cstate->force_notnull_flags[m])
3701  {
3702  /*
3703  * FORCE_NOT_NULL option is set and column is NULL -
3704  * convert it to the NULL string.
3705  */
3706  string = cstate->null_print;
3707  }
3708  else if (string != NULL && cstate->force_null_flags[m]
3709  && strcmp(string, cstate->null_print) == 0)
3710  {
3711  /*
3712  * FORCE_NULL option is set and column matches the NULL
3713  * string. It must have been quoted, or otherwise the
3714  * string would already have been set to NULL. Convert it
3715  * to NULL as specified.
3716  */
3717  string = NULL;
3718  }
3719  }
3720 
3721  cstate->cur_attname = NameStr(att->attname);
3722  cstate->cur_attval = string;
3723  values[m] = InputFunctionCall(&in_functions[m],
3724  string,
3725  typioparams[m],
3726  att->atttypmod);
3727  if (string != NULL)
3728  nulls[m] = false;
3729  cstate->cur_attname = NULL;
3730  cstate->cur_attval = NULL;
3731  }
3732 
3733  Assert(fieldno == attr_count);
3734  }
3735  else
3736  {
3737  /* binary */
3738  int16 fld_count;
3739  ListCell *cur;
3740 
3741  cstate->cur_lineno++;
3742 
3743  if (!CopyGetInt16(cstate, &fld_count))
3744  {
3745  /* EOF detected (end of file, or protocol-level EOF) */
3746  return false;
3747  }
3748 
3749  if (fld_count == -1)
3750  {
3751  /*
3752  * Received EOF marker. In a V3-protocol copy, wait for the
3753  * protocol-level EOF, and complain if it doesn't come
3754  * immediately. This ensures that we correctly handle CopyFail,
3755  * if client chooses to send that now.
3756  *
3757  * Note that we MUST NOT try to read more data in an old-protocol
3758  * copy, since there is no protocol-level EOF marker then. We
3759  * could go either way for copy from file, but choose to throw
3760  * error if there's data after the EOF marker, for consistency
3761  * with the new-protocol case.
3762  */
3763  char dummy;
3764 
3765  if (cstate->copy_dest != COPY_OLD_FE &&
3766  CopyGetData(cstate, &dummy, 1, 1) > 0)
3767  ereport(ERROR,
3768  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3769  errmsg("received copy data after EOF marker")));
3770  return false;
3771  }
3772 
3773  if (fld_count != attr_count)
3774  ereport(ERROR,
3775  (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
3776  errmsg("row field count is %d, expected %d",
3777  (int) fld_count, attr_count)));
3778 
3779  i = 0;
3780  foreach(cur, cstate->attnumlist)
3781  {
3782  int attnum = lfirst_int(cur);
3783  int m = attnum - 1;
3784  Form_pg_attribute att = TupleDescAttr(tupDesc, m);
3785 
3786  cstate->cur_attname = NameStr(att->attname);
3787  i++;
3788  values[m] = CopyReadBinaryAttribute(cstate,
3789  i,
3790  &in_functions[m],
3791  typioparams[m],
3792  att->atttypmod,
3793  &nulls[m]);
3794  cstate->cur_attname = NULL;
3795  }
3796  }
3797 
3798  /*
3799  * Now compute and insert any defaults available for the columns not
3800  * provided by the input data. Anything not processed here or above will
3801  * remain NULL.
3802  */
3803  for (i = 0; i < num_defaults; i++)
3804  {
3805  /*
3806  * The caller must supply econtext and have switched into the
3807  * per-tuple memory context in it.
3808  */
3809  Assert(econtext != NULL);
3811 
3812  values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
3813  &nulls[defmap[i]]);
3814  }
3815 
3816  return true;
3817 }
signed short int16
Definition: c.h:354
bool NextCopyFromRawFields(CopyState cstate, char ***fields, int *nfields)
Definition: copy.c:3583
static Datum CopyReadBinaryAttribute(CopyState cstate, int column_no, FmgrInfo *flinfo, Oid typioparam, int32 typmod, bool *isnull)
Definition: copy.c:4717
Definition: fmgr.h:56
bool csv_mode
Definition: copy.c:138
bool binary
Definition: copy.c:136
#define RelationGetDescr(relation)
Definition: rel.h:482
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:234
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
unsigned int Oid
Definition: postgres_ext.h:31
bool * force_null_flags
Definition: copy.c:152
bool * convert_select_flags
Definition: copy.c:155
CopyDest copy_dest
Definition: copy.c:117
uint64 cur_lineno
Definition: copy.c:160
char * null_print
Definition: copy.c:140
const char * cur_attname
Definition: copy.c:161
Relation rel
Definition: copy.c:130
#define ERROR
Definition: elog.h:43
static int CopyGetData(CopyState cstate, void *databuf, int minread, int maxread)
Definition: copy.c:611
#define lfirst_int(lc)
Definition: pg_list.h:191
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:290
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
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:738
static int list_length(const List *l)
Definition: pg_list.h:169
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
#define NameStr(name)
Definition: c.h:615
static bool CopyGetInt16(CopyState cstate, int16 *val)
Definition: copy.c:768
const char * cur_attval
Definition: copy.c:162
int16 AttrNumber
Definition: attnum.h:21
int * defmap
Definition: copy.c:181

◆ NextCopyFromRawFields()

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

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

3584 {
3585  int fldct;
3586  bool done;
3587 
3588  /* only available for text or csv input */
3589  Assert(!cstate->binary);
3590 
3591  /* on input just throw the header line away */
3592  if (cstate->cur_lineno == 0 && cstate->header_line)
3593  {
3594  cstate->cur_lineno++;
3595  if (CopyReadLine(cstate))
3596  return false; /* done */
3597  }
3598 
3599  cstate->cur_lineno++;
3600 
3601  /* Actually read the line into memory here */
3602  done = CopyReadLine(cstate);
3603 
3604  /*
3605  * EOF at start of line means we're done. If we see EOF after some
3606  * characters, we act as though it was newline followed by EOF, ie,
3607  * process the line and then exit loop on next iteration.
3608  */
3609  if (done && cstate->line_buf.len == 0)
3610  return false;
3611 
3612  /* Parse the line into de-escaped field values */
3613  if (cstate->csv_mode)
3614  fldct = CopyReadAttributesCSV(cstate);
3615  else
3616  fldct = CopyReadAttributesText(cstate);
3617 
3618  *fields = cstate->raw_fields;
3619  *nfields = fldct;
3620  return true;
3621 }
bool csv_mode
Definition: copy.c:138
char ** raw_fields
Definition: copy.c:202
bool binary
Definition: copy.c:136
StringInfoData line_buf
Definition: copy.c:211
static int CopyReadAttributesCSV(CopyState cstate)
Definition: copy.c:4548
uint64 cur_lineno
Definition: copy.c:160
bool header_line
Definition: copy.c:139
#define Assert(condition)
Definition: c.h:738
static bool CopyReadLine(CopyState cstate)
Definition: copy.c:3839
static int CopyReadAttributesText(CopyState cstate)
Definition: copy.c:4320

◆ ProcessCopyOptions()

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

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

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