PostgreSQL Source Code: src/backend/commands/copy.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

17#include <ctype.h>

19#include <sys/stat.h>

20

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61void

63 int stmt_location, int stmt_len,

65{

66 bool is_from = stmt->is_from;

67 bool pipe = (stmt->filename == NULL);

69 Oid relid;

71 Node *whereClause = NULL;

72

73

74

75

76

77 if (!pipe)

78 {

79 if (stmt->is_program)

80 {

83 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

84 errmsg("permission denied to COPY to or from an external program"),

85 errdetail("Only roles with privileges of the \"%s\" role may COPY to or from an external program.",

86 "pg_execute_server_program"),

87 errhint("Anyone can COPY to stdout or from stdin. "

88 "psql's \\copy command also works for anyone.")));

89 }

90 else

91 {

94 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

95 errmsg("permission denied to COPY from a file"),

96 errdetail("Only roles with privileges of the \"%s\" role may COPY from a file.",

97 "pg_read_server_files"),

98 errhint("Anyone can COPY to stdout or from stdin. "

99 "psql's \\copy command also works for anyone.")));

100

103 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

104 errmsg("permission denied to COPY to a file"),

105 errdetail("Only roles with privileges of the \"%s\" role may COPY to a file.",

106 "pg_write_server_files"),

107 errhint("Anyone can COPY to stdout or from stdin. "

108 "psql's \\copy command also works for anyone.")));

109 }

110 }

111

112 if (stmt->relation)

113 {

118 List *attnums;

120

122

123

125

127

129 NULL, false, false);

130

133

134 if (stmt->whereClause)

135 {

136

138

139

141

142

144

145

147

149

152 }

153

156 foreach(cur, attnums)

157 {

158 int attno;

160

163

165 }

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

183 {

189

190 if (is_from)

192 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

193 errmsg("COPY FROM not supported with row-level security"),

194 errhint("Use INSERT statements instead.")));

195

196

197

198

199

200

201

202

203

204

205

206

207

208 if (stmt->attlist)

209 {

213

215 target->name = NULL;

217 target->val = (Node *) cr;

219

221 }

222 else

223 {

225

226 foreach(lc, stmt->attlist)

227 {

228

229

230

231

232

236

237

239 target->name = NULL;

241 target->val = (Node *) cr;

243

244

245 targetList = lappend(targetList, target);

246 }

247 }

248

249

250

251

252

253

254

257 -1);

258 from->inh = false;

259

260

262 select->targetList = targetList;

264

269

270

271

272

273

274

275

277 rel = NULL;

278 }

279 }

280 else

281 {

283

288

290 rel = NULL;

291 }

292

293 if (is_from)

294 {

296

298

299

302

304 stmt->filename, stmt->is_program,

305 NULL, stmt->attlist, stmt->options);

306 *processed = CopyFrom(cstate);

308 }

309 else

310 {

312

313 cstate = BeginCopyTo(pstate, rel, query, relid,

314 stmt->filename, stmt->is_program,

315 NULL, stmt->attlist, stmt->options);

316 *processed = DoCopyTo(cstate);

318 }

319

320 if (rel != NULL)

322}

323

324

325

326

327

330{

331

332

333

334 if (def->arg == NULL)

336

337

338

339

341 {

342 case T_Integer:

344 {

345 case 0:

347 case 1:

349 default:

350

351 break;

352 }

353 break;

354 default:

355 {

357

358

359

360

361

371 {

372 if (!is_from)

374 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

375 errmsg("cannot use \"%s\" with HEADER in COPY TO",

376 sval)));

378 }

379 }

380 break;

381 }

383 (errcode(ERRCODE_SYNTAX_ERROR),

384 errmsg("%s requires a Boolean value or \"match\"",

387}

388

389

390

391

394{

396

397 if (!is_from)

399 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

400

401

402 errmsg("COPY %s cannot be used with %s", "ON_ERROR", "COPY TO"),

404

405

406

407

412

414 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

415

416 errmsg("COPY %s \"%s\" not recognized", "ON_ERROR", sval),

419}

420

421

422

423

424

425

426

427

430{

431 int64 reject_limit;

432

433 if (def->arg == NULL)

435 (errcode(ERRCODE_SYNTAX_ERROR),

436 errmsg("%s requires a numeric value",

438 else if (nodeTag(def->arg) == T_String)

440 else

442

443 if (reject_limit <= 0)

445 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

446 errmsg("REJECT_LIMIT (%" PRId64 ") must be greater than zero",

447 reject_limit)));

448

449 return reject_limit;

450}

451

452

453

454

457{

458 char *sval;

459

460

461

462

470

472 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

473

474 errmsg("COPY %s \"%s\" not recognized", "LOG_VERBOSITY", sval),

477}

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495void

498 bool is_from,

500{

501 bool format_specified = false;

502 bool freeze_specified = false;

503 bool header_specified = false;

504 bool on_error_specified = false;

505 bool log_verbosity_specified = false;

506 bool reject_limit_specified = false;

508

509

510 if (opts_out == NULL)

512

514

515

517 {

519

520 if (strcmp(defel->defname, "format") == 0)

521 {

523

524 if (format_specified)

526 format_specified = true;

527 if (strcmp(fmt, "text") == 0)

528 ;

529 else if (strcmp(fmt, "csv") == 0)

531 else if (strcmp(fmt, "binary") == 0)

532 opts_out->binary = true;

533 else

535 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

536 errmsg("COPY format \"%s\" not recognized", fmt),

538 }

539 else if (strcmp(defel->defname, "freeze") == 0)

540 {

541 if (freeze_specified)

543 freeze_specified = true;

545 }

546 else if (strcmp(defel->defname, "delimiter") == 0)

547 {

548 if (opts_out->delim)

551 }

552 else if (strcmp(defel->defname, "null") == 0)

553 {

557 }

558 else if (strcmp(defel->defname, "default") == 0)

559 {

563 }

564 else if (strcmp(defel->defname, "header") == 0)

565 {

566 if (header_specified)

568 header_specified = true;

570 }

571 else if (strcmp(defel->defname, "quote") == 0)

572 {

573 if (opts_out->quote)

576 }

577 else if (strcmp(defel->defname, "escape") == 0)

578 {

579 if (opts_out->escape)

582 }

583 else if (strcmp(defel->defname, "force_quote") == 0)

584 {

591 else

593 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

594 errmsg("argument to option \"%s\" must be a list of column names",

597 }

598 else if (strcmp(defel->defname, "force_not_null") == 0)

599 {

606 else

608 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

609 errmsg("argument to option \"%s\" must be a list of column names",

612 }

613 else if (strcmp(defel->defname, "force_null") == 0)

614 {

621 else

623 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

624 errmsg("argument to option \"%s\" must be a list of column names",

627 }

628 else if (strcmp(defel->defname, "convert_selectively") == 0)

629 {

630

631

632

633

634

640 else

642 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

643 errmsg("argument to option \"%s\" must be a list of column names",

646 }

647 else if (strcmp(defel->defname, "encoding") == 0)

648 {

654 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

655 errmsg("argument to option \"%s\" must be a valid encoding name",

658 }

659 else if (strcmp(defel->defname, "on_error") == 0)

660 {

661 if (on_error_specified)

663 on_error_specified = true;

665 }

666 else if (strcmp(defel->defname, "log_verbosity") == 0)

667 {

668 if (log_verbosity_specified)

670 log_verbosity_specified = true;

672 }

673 else if (strcmp(defel->defname, "reject_limit") == 0)

674 {

675 if (reject_limit_specified)

677 reject_limit_specified = true;

679 }

680 else

682 (errcode(ERRCODE_SYNTAX_ERROR),

683 errmsg("option \"%s\" not recognized",

686 }

687

688

689

690

691

694 (errcode(ERRCODE_SYNTAX_ERROR),

695

696 errmsg("cannot specify %s in BINARY mode", "DELIMITER")));

697

700 (errcode(ERRCODE_SYNTAX_ERROR),

701 errmsg("cannot specify %s in BINARY mode", "NULL")));

702

705 (errcode(ERRCODE_SYNTAX_ERROR),

706 errmsg("cannot specify %s in BINARY mode", "DEFAULT")));

707

708

709 if (!opts_out->delim)

710 opts_out->delim = opts_out->csv_mode ? "," : "\t";

711

715

717 {

718 if (!opts_out->quote)

719 opts_out->quote = "\"";

720 if (!opts_out->escape)

722 }

723

724

725 if (strlen(opts_out->delim) != 1)

727 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

728 errmsg("COPY delimiter must be a single one-byte character")));

729

730

731 if (strchr(opts_out->delim, '\r') != NULL ||

732 strchr(opts_out->delim, '\n') != NULL)

734 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

735 errmsg("COPY delimiter cannot be newline or carriage return")));

736

737 if (strchr(opts_out->null_print, '\r') != NULL ||

738 strchr(opts_out->null_print, '\n') != NULL)

740 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

741 errmsg("COPY null representation cannot use newline or carriage return")));

742

744 {

746

747 if (strchr(opts_out->default_print, '\r') != NULL ||

750 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

751 errmsg("COPY default representation cannot use newline or carriage return")));

752 }

753

754

755

756

757

758

759

760

761

762

763

765 strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",

766 opts_out->delim[0]) != NULL)

768 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

769 errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));

770

771

774 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

775

776 errmsg("cannot specify %s in BINARY mode", "HEADER")));

777

778

779 if (!opts_out->csv_mode && opts_out->quote != NULL)

781 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

782

783 errmsg("COPY %s requires CSV mode", "QUOTE")));

784

785 if (opts_out->csv_mode && strlen(opts_out->quote) != 1)

787 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

788 errmsg("COPY quote must be a single one-byte character")));

789

792 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

793 errmsg("COPY delimiter and quote must be different")));

794

795

798 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

799

800 errmsg("COPY %s requires CSV mode", "ESCAPE")));

801

802 if (opts_out->csv_mode && strlen(opts_out->escape) != 1)

804 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

805 errmsg("COPY escape must be a single one-byte character")));

806

807

810 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

811

812 errmsg("COPY %s requires CSV mode", "FORCE_QUOTE")));

815 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

816

817

818 errmsg("COPY %s cannot be used with %s", "FORCE_QUOTE",

819 "COPY FROM")));

820

821

825 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

826

827 errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));

829 !is_from)

831 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

832

833

834 errmsg("COPY %s cannot be used with %s", "FORCE_NOT_NULL",

835 "COPY TO")));

836

837

841 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

842

843 errmsg("COPY %s requires CSV mode", "FORCE_NULL")));

844

846 !is_from)

848 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

849

850

851 errmsg("COPY %s cannot be used with %s", "FORCE_NULL",

852 "COPY TO")));

853

854

855 if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL)

857 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

858

859 errmsg("COPY delimiter character must not appear in the %s specification",

860 "NULL")));

861

862

864 strchr(opts_out->null_print, opts_out->quote[0]) != NULL)

866 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

867

868 errmsg("CSV quote character must not appear in the %s specification",

869 "NULL")));

870

871

872 if (opts_out->freeze && !is_from)

874 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

875

876

877 errmsg("COPY %s cannot be used with %s", "FREEZE",

878 "COPY TO")));

879

881 {

882 if (!is_from)

884 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

885

886

887 errmsg("COPY %s cannot be used with %s", "DEFAULT",

888 "COPY TO")));

889

890

893 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

894

895 errmsg("COPY delimiter character must not appear in the %s specification",

896 "DEFAULT")));

897

898

902 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

903

904 errmsg("CSV quote character must not appear in the %s specification",

905 "DEFAULT")));

906

907

912 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

913 errmsg("NULL specification and DEFAULT specification cannot be the same")));

914 }

915

918 (errcode(ERRCODE_SYNTAX_ERROR),

919 errmsg("only ON_ERROR STOP is allowed in BINARY mode")));

920

923 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

924

925

926 errmsg("COPY %s requires %s to be set to %s",

927 "REJECT_LIMIT", "ON_ERROR", "IGNORE")));

928}

929

930

931

932

933

934

935

936

937

938

939

940

941

942

943

946{

948

949 if (attnamelist == NIL)

950 {

951

952 int attr_count = tupDesc->natts;

953 int i;

954

955 for (i = 0; i < attr_count; i++)

956 {

958

960 continue;

962 }

963 }

964 else

965 {

966

968

969 foreach(l, attnamelist)

970 {

973 int i;

974

975

977 for (i = 0; i < tupDesc->natts; i++)

978 {

980

981 if (att->attisdropped)

982 continue;

984 {

985 if (att->attgenerated)

987 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),

988 errmsg("column \"%s\" is a generated column",

990 errdetail("Generated columns cannot be used in COPY.")));

991 attnum = att->attnum;

992 break;

993 }

994 }

996 {

997 if (rel != NULL)

999 (errcode(ERRCODE_UNDEFINED_COLUMN),

1000 errmsg("column \"%s\" of relation \"%s\" does not exist",

1002 else

1004 (errcode(ERRCODE_UNDEFINED_COLUMN),

1005 errmsg("column \"%s\" does not exist",

1007 }

1008

1011 (errcode(ERRCODE_DUPLICATE_COLUMN),

1012 errmsg("column \"%s\" specified more than once",

1015 }

1016 }

1017

1018 return attnums;

1019}

bool has_privs_of_role(Oid member, Oid role)

#define InvalidAttrNumber

static CopyHeaderChoice defGetCopyHeaderChoice(DefElem *def, bool is_from)

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

static int64 defGetCopyRejectLimitOption(DefElem *def)

List * CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)

static CopyOnErrorChoice defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)

void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options)

static CopyLogVerbosityChoice defGetCopyLogVerbosityChoice(DefElem *def, ParseState *pstate)

Bitmapset * bms_add_member(Bitmapset *a, int x)

Node * eval_const_expressions(PlannerInfo *root, Node *node)

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

uint64 CopyFrom(CopyFromState cstate)

void EndCopyFrom(CopyFromState cstate)

uint64 DoCopyTo(CopyToState cstate)

CopyToState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *raw_query, Oid queryRelId, const char *filename, bool is_program, copy_data_dest_cb data_dest_cb, List *attnamelist, List *options)

void EndCopyTo(CopyToState cstate)

char * defGetString(DefElem *def)

bool defGetBoolean(DefElem *def)

int64 defGetInt64(DefElem *def)

void errorConflictingDefElem(DefElem *defel, ParseState *pstate)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)

Assert(PointerIsAligned(start, uint64))

@ COPY_LOG_VERBOSITY_SILENT

@ COPY_LOG_VERBOSITY_VERBOSE

@ COPY_LOG_VERBOSITY_DEFAULT

List * lappend(List *list, void *datum)

List * lappend_int(List *list, int datum)

bool list_member_int(const List *list, int datum)

char * get_namespace_name(Oid nspid)

RangeVar * makeRangeVar(char *schemaname, char *relname, int location)

List * make_ands_implicit(Expr *clause)

char * pstrdup(const char *in)

void * palloc0(Size size)

int namestrcmp(Name name, const char *str)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

int64 pg_strtoint64(const char *s)

Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)

void assign_expr_collations(ParseState *pstate, Node *expr)

Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)

int parser_errposition(ParseState *pstate, int location)

ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)

void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)

FormData_pg_attribute * Form_pg_attribute

#define lfirst_node(type, lc)

#define pg_char_to_encoding

int pg_strcasecmp(const char *s1, const char *s2)

Expr * canonicalize_qual(Expr *qual, bool is_check)

#define RelationGetRelid(relation)

#define RelationGetDescr(relation)

#define RelationGetRelationName(relation)

#define RelationGetNamespace(relation)

int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)

CopyLogVerbosityChoice log_verbosity

CopyOnErrorChoice on_error

CopyHeaderChoice header_line

RTEPermissionInfo * p_perminfo

#define FirstLowInvalidHeapAttributeNumber

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)

void PreventCommandIfReadOnly(const char *cmdname)

#define select(n, r, w, e, timeout)