Michael Fuhr wrote:
On Sat, Feb 03, 2007 at 10:52:29AM -0600, Andrew Dunstan wrote:
I'd say fix psql. Not sure how far back we should backpatch it. It's
interesting that this has been there since 8.0 and is only now discovered.

The problem is new in 8.2 because COPY (query) doesn't support USING
DELIMITERS.  COPY tablename does, so it has worked all along.


oh, good point. OK, I have cut this quick patch that will continue to accept the legacy syntax in psql in non-inline-query cases, but will make psql unreservedly emit new style syntax for COPY to the backend. Does that seem reasonable, or is it too much of a change for the stable branch?

cheers

andrew
Index: src/bin/psql/copy.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/copy.c,v
retrieving revision 1.72
diff -c -r1.72 copy.c
*** src/bin/psql/copy.c	5 Jan 2007 22:19:49 -0000	1.72
--- src/bin/psql/copy.c	3 Feb 2007 19:37:34 -0000
***************
*** 118,123 ****
--- 118,124 ----
  	char	   *token;
  	const char *whitespace = " \t\n\r";
  	char		nonstd_backslash = standard_strings() ? 0 : '\\';
+ 	bool        have_query = false;
  
  	if (args)
  		line = pg_strdup(args);
***************
*** 163,168 ****
--- 164,170 ----
  			xstrcat(&result->table, " ");
  			xstrcat(&result->table, token);
  		}
+ 		have_query = true;
  	}
  
  	token = strtokx(NULL, whitespace, ".,()", "\"",
***************
*** 268,291 ****
  					0, false, false, pset.encoding);
  
  	/*
! 	 * Allows old COPY syntax for backward compatibility 2002-06-19
  	 */
! 	if (token && pg_strcasecmp(token, "using") == 0)
! 	{
! 		token = strtokx(NULL, whitespace, NULL, NULL,
! 						0, false, false, pset.encoding);
! 		if (!(token && pg_strcasecmp(token, "delimiters") == 0))
! 			goto error;
! 	}
! 	if (token && pg_strcasecmp(token, "delimiters") == 0)
  	{
! 		token = strtokx(NULL, whitespace, NULL, "'",
! 						nonstd_backslash, true, false, pset.encoding);
! 		if (!token)
! 			goto error;
! 		result->delim = pg_strdup(token);
! 		token = strtokx(NULL, whitespace, NULL, NULL,
! 						0, false, false, pset.encoding);
  	}
  
  	if (token)
--- 270,297 ----
  					0, false, false, pset.encoding);
  
  	/*
! 	 * Allows old COPY syntax for backward compatibility.
! 	 * Skip if we have an inline query instead of a table name.
  	 */
! 	if (! have_query)
  	{
! 		if (token && pg_strcasecmp(token, "using") == 0)
! 		{
! 			token = strtokx(NULL, whitespace, NULL, NULL,
! 							0, false, false, pset.encoding);
! 			if (!(token && pg_strcasecmp(token, "delimiters") == 0))
! 				goto error;
! 		}
! 		if (token && pg_strcasecmp(token, "delimiters") == 0)
! 		{
! 			token = strtokx(NULL, whitespace, NULL, "'",
! 							nonstd_backslash, true, false, pset.encoding);
! 			if (!token)
! 				goto error;
! 			result->delim = pg_strdup(token);
! 			token = strtokx(NULL, whitespace, NULL, NULL,
! 							0, false, false, pset.encoding);
! 		}
  	}
  
  	if (token)
***************
*** 480,511 ****
  
  	printfPQExpBuffer(&query, "COPY ");
  
- 	/* Uses old COPY syntax for backward compatibility 2002-06-19 */
- 	if (options->binary)
- 		appendPQExpBuffer(&query, "BINARY ");
- 
  	appendPQExpBuffer(&query, "%s ", options->table);
  
  	if (options->column_list)
  		appendPQExpBuffer(&query, "%s ", options->column_list);
  
- 	/* Uses old COPY syntax for backward compatibility 2002-06-19 */
- 	if (options->oids)
- 		appendPQExpBuffer(&query, "WITH OIDS ");
- 
  	if (options->from)
  		appendPQExpBuffer(&query, "FROM STDIN");
  	else
  		appendPQExpBuffer(&query, "TO STDOUT");
  
  
! 	/* Uses old COPY syntax for backward compatibility 2002-06-19 */
  	if (options->delim)
! 		emit_copy_option(&query, " USING DELIMITERS ", options->delim);
  
- 	/* There is no backward-compatible CSV syntax */
  	if (options->null)
! 		emit_copy_option(&query, " WITH NULL AS ", options->null);
  
  	if (options->csv_mode)
  		appendPQExpBuffer(&query, " CSV");
--- 486,513 ----
  
  	printfPQExpBuffer(&query, "COPY ");
  
  	appendPQExpBuffer(&query, "%s ", options->table);
  
  	if (options->column_list)
  		appendPQExpBuffer(&query, "%s ", options->column_list);
  
  	if (options->from)
  		appendPQExpBuffer(&query, "FROM STDIN");
  	else
  		appendPQExpBuffer(&query, "TO STDOUT");
  
  
! 	if (options->binary)
! 		appendPQExpBuffer(&query, " BINARY ");
! 
! 	if (options->oids)
! 		appendPQExpBuffer(&query, " OIDS ");
! 
  	if (options->delim)
! 		emit_copy_option(&query, " DELIMITER ", options->delim);
  
  	if (options->null)
! 		emit_copy_option(&query, " NULL AS ", options->null);
  
  	if (options->csv_mode)
  		appendPQExpBuffer(&query, " CSV");
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to