diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index f14fae3308..f4348a6197 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -611,7 +611,7 @@ ProcessCopyOptions(ParseState *pstate, } /* Only single-byte delimiter strings are supported. */ - if (strlen(opts_out->delim) != 1) + if (strlen(opts_out->delim) > 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY delimiter must be a single one-byte character"))); @@ -669,12 +669,15 @@ ProcessCopyOptions(ParseState *pstate, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY quote available only in CSV mode"))); - if (opts_out->csv_mode && strlen(opts_out->quote) != 1) + if (opts_out->csv_mode && strlen(opts_out->quote) > 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY quote must be a single one-byte character"))); - if (opts_out->csv_mode && opts_out->delim[0] == opts_out->quote[0]) + if (opts_out->csv_mode && + opts_out->delim[0] == opts_out->quote[0] && + opts_out->delim[0] != '\0' && + opts_out->quote[0] != '\0') ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY delimiter and quote must be different"))); @@ -685,7 +688,7 @@ ProcessCopyOptions(ParseState *pstate, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY escape available only in CSV mode"))); - if (opts_out->csv_mode && strlen(opts_out->escape) != 1) + if (opts_out->csv_mode && strlen(opts_out->escape) > 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY escape must be a single one-byte character"))); @@ -722,14 +725,16 @@ ProcessCopyOptions(ParseState *pstate, errmsg("COPY force null only available using COPY FROM"))); /* Don't allow the delimiter to appear in the null string. */ - if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL) + if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL && + opts_out->delim[0] != '\0') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY delimiter must not appear in the NULL specification"))); /* Don't allow the CSV quote char to appear in the null string. */ if (opts_out->csv_mode && - strchr(opts_out->null_print, opts_out->quote[0]) != NULL) + strchr(opts_out->null_print, opts_out->quote[0]) != NULL && + opts_out->quote[0] != '\0') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("CSV quote character must not appear in the NULL specification"))); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6f5aa8a3cb..e0c2002b50 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3409,6 +3409,10 @@ copy_opt_item: { $$ = makeDefElem("delimiter", (Node *) makeString($3), @1); } + | DELIMITER NONE + { + $$ = makeDefElem("delimiter", (Node *) makeString("\0"), @1); + } | NULL_P opt_as Sconst { $$ = makeDefElem("null", (Node *) makeString($3), @1); @@ -3425,6 +3429,10 @@ copy_opt_item: { $$ = makeDefElem("quote", (Node *) makeString($3), @1); } + | QUOTE NONE + { + $$ = makeDefElem("quote", (Node *) makeString("\0"), @1); + } | ESCAPE opt_as Sconst { $$ = makeDefElem("escape", (Node *) makeString($3), @1);