Stephen Frost wrote:
-- Start of PGP signed section.
> Greetings,
>
> psql seems to accept syntax which would be rejected by the server,
> which seems a bit odd:
>
> sfrost*=# \copy billing_data from ../BillingSamplePricerFile.csv
> with csv header quote as '"' null as 'abc' null as '123'
> ERROR: invalid input syntax for integer: ""
>
> vs.
>
> sfrost=# copy billing_data from stdin
> with csv header quote as '"' null as 'abc' null as '123';
> ERROR: conflicting or redundant options
>
> Now, honestly, I'd like to see support for multiple 'NULL AS' strings,
> but till that's added it'd probably be best if psql error'd on this
> like the backend does rather than accepting it and then not doing it.
I have fixed this bug with the attached patch to CVS HEAD.
test=> \copy billing_data from ../BillingSamplePricerFile.csv with csv
header quote as '"' null as 'abc' null as '123'
\copy: parse error at "null"
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://postgres.enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Index: src/bin/psql/copy.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/copy.c,v
retrieving revision 1.77
diff -c -c -r1.77 copy.c
*** src/bin/psql/copy.c 1 Jan 2008 19:45:55 -0000 1.77
--- src/bin/psql/copy.c 11 Mar 2008 23:27:15 -0000
***************
*** 274,279 ****
--- 274,281 ----
result->header = true;
else if (pg_strcasecmp(token, "delimiter") == 0)
{
+ if (result->delim)
+ goto error;
token = strtokx(NULL, whitespace, NULL, "'",
nonstd_backslash, true, false, pset.encoding);
if (token && pg_strcasecmp(token, "as") == 0)
***************
*** 286,291 ****
--- 288,295 ----
}
else if (pg_strcasecmp(token, "null") == 0)
{
+ if (result->null)
+ goto error;
token = strtokx(NULL, whitespace, NULL, "'",
nonstd_backslash, true, false, pset.encoding);
if (token && pg_strcasecmp(token, "as") == 0)
***************
*** 298,303 ****
--- 302,309 ----
}
else if (pg_strcasecmp(token, "quote") == 0)
{
+ if (result->quote)
+ goto error;
token = strtokx(NULL, whitespace, NULL, "'",
nonstd_backslash, true, false, pset.encoding);
if (token && pg_strcasecmp(token, "as") == 0)
***************
*** 310,315 ****
--- 316,323 ----
}
else if (pg_strcasecmp(token, "escape") == 0)
{
+ if (result->escape)
+ goto error;
token = strtokx(NULL, whitespace, NULL, "'",
nonstd_backslash, true, false, pset.encoding);
if (token && pg_strcasecmp(token, "as") == 0)
***************
*** 326,331 ****
--- 334,341 ----
0, false, false, pset.encoding);
if (pg_strcasecmp(token, "quote") == 0)
{
+ if (result->force_quote_list)
+ goto error;
/* handle column list */
fetch_next = false;
for (;;)
***************
*** 347,352 ****
--- 357,364 ----
}
else if (pg_strcasecmp(token, "not") == 0)
{
+ if (result->force_notnull_list)
+ goto error;
token = strtokx(NULL, whitespace, ",", "\"",
0, false, false, pset.encoding);
if (pg_strcasecmp(token, "null") != 0)