* Process the statement option list for COPY. * * Scan the options list (a list of DefElem) and transpose the information * into *opts_out, applying appropriate error checking. * * If 'opts_out' is not NULL, it is assumed to be filled with zeroes initially. * * This is exported so that external users of the COPY API can sanity-check * a list of options. In that usage, 'opts_out' can be pa
| 552 | * self-consistency of the options list. |
| 553 | */ |
| 554 | void |
| 555 | ProcessCopyOptions(ParseState *pstate, |
| 556 | CopyFormatOptions *opts_out, |
| 557 | bool is_from, |
| 558 | List *options, |
| 559 | Oid rel_oid) |
| 560 | { |
| 561 | bool format_specified = false; |
| 562 | bool freeze_specified = false; |
| 563 | bool header_specified = false; |
| 564 | ListCell *option; |
| 565 | |
| 566 | /* Support external use for option sanity checking */ |
| 567 | if (opts_out == NULL) |
| 568 | opts_out = (CopyFormatOptions *) palloc0(sizeof(CopyFormatOptions)); |
| 569 | |
| 570 | opts_out->skip_foreign_partitions = false; |
| 571 | |
| 572 | opts_out->delim_off = false; |
| 573 | opts_out->file_encoding = -1; |
| 574 | |
| 575 | /* Extract options from the statement node tree */ |
| 576 | foreach(option, options) |
| 577 | { |
| 578 | DefElem *defel = lfirst_node(DefElem, option); |
| 579 | |
| 580 | if (strcmp(defel->defname, "format") == 0) |
| 581 | { |
| 582 | char *fmt = defGetString(defel); |
| 583 | |
| 584 | if (format_specified) |
| 585 | ereport(ERROR, |
| 586 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 587 | errmsg("conflicting or redundant options"), |
| 588 | parser_errposition(pstate, defel->location))); |
| 589 | format_specified = true; |
| 590 | if (strcmp(fmt, "text") == 0) |
| 591 | /* default format */ ; |
| 592 | else if (strcmp(fmt, "csv") == 0) |
| 593 | opts_out->csv_mode = true; |
| 594 | else if (strcmp(fmt, "binary") == 0) |
| 595 | opts_out->binary = true; |
| 596 | else |
| 597 | ereport(ERROR, |
| 598 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 599 | errmsg("COPY format \"%s\" not recognized", fmt), |
| 600 | parser_errposition(pstate, defel->location))); |
| 601 | } |
| 602 | else if (strcmp(defel->defname, "freeze") == 0) |
| 603 | { |
| 604 | if (freeze_specified) |
| 605 | ereport(ERROR, |
| 606 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 607 | errmsg("conflicting or redundant options"), |
| 608 | parser_errposition(pstate, defel->location))); |
| 609 | freeze_specified = true; |
| 610 | opts_out->freeze = defGetBoolean(defel); |
| 611 | } |
no test coverage detected