@ -3,7 +3,7 @@
*
* Copyright ( c ) 2000 - 2006 , PostgreSQL Global Development Group
*
* $ PostgreSQL : pgsql / src / bin / psql / copy . c , v 1.62 2006 / 05 / 31 11 : 02 : 42 momjian Exp $
* $ PostgreSQL : pgsql / src / bin / psql / copy . c , v 1.63 2006 / 06 / 01 00 : 15 : 36 tgl Exp $
*/
# include "postgres_fe.h"
# include "copy.h"
@ -19,6 +19,7 @@
# include "libpq-fe.h"
# include "pqexpbuffer.h"
# include "pqsignal.h"
# include "dumputils.h"
# include "settings.h"
# include "common.h"
@ -113,6 +114,7 @@ parse_slash_copy(const char *args)
char * line ;
char * token ;
const char * whitespace = " \t \n \r " ;
char nonstd_backslash = standard_strings ( ) ? 0 : ' \\ ' ;
if ( args )
line = pg_strdup ( args ) ;
@ -216,7 +218,7 @@ parse_slash_copy(const char *args)
goto error ;
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , true , pset . encoding ) ;
nonstd_backslash , true , pset . encoding ) ;
if ( ! token )
goto error ;
@ -255,7 +257,7 @@ parse_slash_copy(const char *args)
if ( token & & pg_strcasecmp ( token , " delimiters " ) = = 0 )
{
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( ! token )
goto error ;
result - > delim = pg_strdup ( token ) ;
@ -290,10 +292,10 @@ parse_slash_copy(const char *args)
else if ( pg_strcasecmp ( token , " delimiter " ) = = 0 )
{
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token & & pg_strcasecmp ( token , " as " ) = = 0 )
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token )
result - > delim = pg_strdup ( token ) ;
else
@ -302,10 +304,10 @@ parse_slash_copy(const char *args)
else if ( pg_strcasecmp ( token , " null " ) = = 0 )
{
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token & & pg_strcasecmp ( token , " as " ) = = 0 )
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token )
result - > null = pg_strdup ( token ) ;
else
@ -314,10 +316,10 @@ parse_slash_copy(const char *args)
else if ( pg_strcasecmp ( token , " quote " ) = = 0 )
{
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token & & pg_strcasecmp ( token , " as " ) = = 0 )
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token )
result - > quote = pg_strdup ( token ) ;
else
@ -326,10 +328,10 @@ parse_slash_copy(const char *args)
else if ( pg_strcasecmp ( token , " escape " ) = = 0 )
{
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token & & pg_strcasecmp ( token , " as " ) = = 0 )
token = strtokx ( NULL , whitespace , NULL , " ' " ,
standard_strings ( ) ? 0 : ' \\ ' , false , pset . encoding ) ;
nonstd_backslash , false , pset . encoding ) ;
if ( token )
result - > escape = pg_strdup ( token ) ;
else
@ -461,23 +463,27 @@ do_copy(const char *args)
/* Uses old COPY syntax for backward compatibility 2002-06-19 */
if ( options - > delim )
{
/* if user gave a quoted string, use it as-is */
if ( options - > delim [ 0 ] = = ' \' ' )
appendPQExpBuffer ( & query , " USING DELIMITERS %c%s " ,
NEED_E_STR ( options - > delim ) , options - > delim ) ;
appendPQExpBuffer ( & query , " USING DELIMITERS %s " , options - > delim ) ;
else
appendPQExpBuffer ( & query , " USING DELIMITERS %c'%s' " ,
NEED_E_STR ( options - > delim ) , options - > delim ) ;
{
appendPQExpBuffer ( & query , " USING DELIMITERS " ) ;
appendStringLiteralConn ( & query , options - > delim , pset . db ) ;
}
}
/* There is no backward-compatible CSV syntax */
if ( options - > null )
{
/* if user gave a quoted string, use it as-is */
if ( options - > null [ 0 ] = = ' \' ' )
appendPQExpBuffer ( & query , " WITH NULL AS %c%s " ,
NEED_E_STR ( options - > null ) , options - > null ) ;
appendPQExpBuffer ( & query , " WITH NULL AS %s " , options - > null ) ;
else
appendPQExpBuffer ( & query , " WITH NULL AS %c'%s' " ,
NEED_E_STR ( options - > null ) , options - > null ) ;
{
appendPQExpBuffer ( & query , " WITH NULL AS " ) ;
appendStringLiteralConn ( & query , options - > null , pset . db ) ;
}
}
if ( options - > csv_mode )
@ -488,22 +494,26 @@ do_copy(const char *args)
if ( options - > quote )
{
/* if user gave a quoted string, use it as-is */
if ( options - > quote [ 0 ] = = ' \' ' )
appendPQExpBuffer ( & query , " QUOTE AS %c%s " ,
NEED_E_STR ( options - > quote ) , options - > quote ) ;
appendPQExpBuffer ( & query , " QUOTE AS %s " , options - > quote ) ;
else
appendPQExpBuffer ( & query , " QUOTE AS %c'%s' " ,
NEED_E_STR ( options - > quote ) , options - > quote ) ;
{
appendPQExpBuffer ( & query , " QUOTE AS " ) ;
appendStringLiteralConn ( & query , options - > quote , pset . db ) ;
}
}
if ( options - > escape )
{
/* if user gave a quoted string, use it as-is */
if ( options - > escape [ 0 ] = = ' \' ' )
appendPQExpBuffer ( & query , " ESCAPE AS %c%s " ,
NEED_E_STR ( options - > escape ) , options - > escape ) ;
appendPQExpBuffer ( & query , " ESCAPE AS %s " , options - > escape ) ;
else
appendPQExpBuffer ( & query , " ESCAPE AS %c'%s' " ,
NEED_E_STR ( options - > escape ) , options - > escape ) ;
{
appendPQExpBuffer ( & query , " ESCAPE AS " ) ;
appendStringLiteralConn ( & query , options - > escape , pset . db ) ;
}
}
if ( options - > force_quote_list )