*** ./doc/src/sgml/libpq.sgml.orig	2009-12-02 15:07:25.000000000 +0100
--- ./doc/src/sgml/libpq.sgml	2010-01-05 14:16:17.062921916 +0100
***************
*** 2926,3032 ****
     <title>Escaping Strings for Inclusion in SQL Commands</title>
  
     <indexterm zone="libpq-exec-escape-string">
-     <primary>PQescapeStringConn</primary>
-    </indexterm>
-    <indexterm zone="libpq-exec-escape-string">
-     <primary>PQescapeString</primary>
-    </indexterm>
-    <indexterm zone="libpq-exec-escape-string">
      <primary>escaping strings</primary>
      <secondary>in libpq</secondary>
     </indexterm>
  
!    <para>
!     <function>PQescapeStringConn</function> escapes a string for use within an SQL
!     command.  This is useful when inserting data values as literal constants
!     in SQL commands.  Certain characters (such as quotes and backslashes) must
!     be escaped to prevent them from being interpreted specially by the SQL parser.
!     <function>PQescapeStringConn</> performs this operation.
!    </para>
  
!    <tip>
!     <para>
!      It is especially important to do proper escaping when handling strings that
!      were received from an untrustworthy source.  Otherwise there is a security
!      risk: you are vulnerable to <quote>SQL injection</> attacks wherein unwanted
!      SQL commands are fed to your database.
!     </para>
!    </tip>
  
!    <para>
!     Note that it is not necessary nor correct to do escaping when a data
!     value is passed as a separate parameter in <function>PQexecParams</> or
!     its sibling routines.
  
!     <synopsis>
       size_t PQescapeStringConn (PGconn *conn,
                                  char *to, const char *from, size_t length,
                                  int *error);
!     </synopsis>
!    </para>
  
!    <para>
!     <function>PQescapeStringConn</> writes an escaped version of the
!     <parameter>from</> string to the <parameter>to</> buffer, escaping
!     special characters so that they cannot cause any harm, and adding a
!     terminating zero byte.  The single quotes that must surround
!     <productname>PostgreSQL</> string literals are not included in the
!     result string; they should be provided in the SQL command that the
!     result is inserted into.  The parameter <parameter>from</> points to
!     the first character of the string that is to be escaped, and the
!     <parameter>length</> parameter gives the number of bytes in this
!     string.  A terminating zero byte is not required, and should not be
!     counted in <parameter>length</>.  (If a terminating zero byte is found
!     before <parameter>length</> bytes are processed,
!     <function>PQescapeStringConn</> stops at the zero; the behavior is
!     thus rather like <function>strncpy</>.) <parameter>to</> shall point
!     to a buffer that is able to hold at least one more byte than twice
!     the value of <parameter>length</>, otherwise the behavior is undefined.
!     Behavior is likewise undefined if the <parameter>to</> and
!     <parameter>from</> strings overlap.
!    </para>
  
!    <para>
!     If the <parameter>error</> parameter is not NULL, then
!     <literal>*error</> is set to zero on success, nonzero on error.
!     Presently the only possible error conditions involve invalid multibyte
!     encoding in the source string.  The output string is still generated
!     on error, but it can be expected that the server will reject it as
!     malformed.  On error, a suitable message is stored in the
!     <parameter>conn</> object, whether or not <parameter>error</> is NULL.
!    </para>
  
!    <para>
!     <function>PQescapeStringConn</> returns the number of bytes written
!     to <parameter>to</>, not including the terminating zero byte.
!    </para>
  
!    <para>
!     <synopsis>
!      size_t PQescapeString (char *to, const char *from, size_t length);
!     </synopsis>
!    </para>
  
!    <para>
!     <function>PQescapeString</> is an older, deprecated version of
!     <function>PQescapeStringConn</>; the difference is that it does
!     not take <parameter>conn</> or <parameter>error</> parameters.
!     Because of this, it cannot adjust its behavior depending on the
!     connection properties (such as character encoding) and therefore
!     <emphasis>it might give the wrong results</>.  Also, it has no way
!     to report error conditions.
!    </para>
  
!    <para>
!     <function>PQescapeString</> can be used safely in single-threaded
!     client programs that work with only one <productname>PostgreSQL</>
!     connection at a time (in this case it can find out what it needs to
!     know <quote>behind the scenes</>).  In other contexts it is a security
!     hazard and should be avoided in favor of
!     <function>PQescapeStringConn</>.
!    </para>
!   </sect2>
  
  
    <sect2 id="libpq-exec-escape-bytea">
     <title>Escaping Binary Strings for Inclusion in SQL Commands</title>
--- 2926,3088 ----
     <title>Escaping Strings for Inclusion in SQL Commands</title>
  
     <indexterm zone="libpq-exec-escape-string">
      <primary>escaping strings</primary>
      <secondary>in libpq</secondary>
     </indexterm>
  
!    <variablelist>
!     <varlistentry>
!      <term>
!       <function>PQescapeStringConn</function>
!       <indexterm>
!        <primary>PQescapeStringConn</primary>
!       </indexterm>
!      </term>
  
!      <listitem>
!       <para>
!        <function>PQescapeStringConn</function> escapes a string for use within an SQL
!        command.  This is useful when inserting data values as literal constants
!        in SQL commands.  Certain characters (such as quotes and backslashes) must
!        be escaped to prevent them from being interpreted specially by the SQL parser.
!        <function>PQescapeStringConn</> performs this operation.
!       </para>
  
!       <tip>
!        <para>
!         It is especially important to do proper escaping when handling strings that
!         were received from an untrustworthy source.  Otherwise there is a security
!         risk: you are vulnerable to <quote>SQL injection</> attacks wherein unwanted
!         SQL commands are fed to your database.
!        </para>
!       </tip>
  
!       <para>
!        Note that it is not necessary nor correct to do escaping when a data
!        value is passed as a separate parameter in <function>PQexecParams</> or
!        its sibling routines.
! 
!        <synopsis>
       size_t PQescapeStringConn (PGconn *conn,
                                  char *to, const char *from, size_t length,
                                  int *error);
!        </synopsis>
!       </para>
  
!       <para>
!        <function>PQescapeStringConn</> writes an escaped version of the
!        <parameter>from</> string to the <parameter>to</> buffer, escaping
!        special characters so that they cannot cause any harm, and adding a
!        terminating zero byte.  The single quotes that must surround
!        <productname>PostgreSQL</> string literals are not included in the
!        result string; they should be provided in the SQL command that the
!        result is inserted into.  The parameter <parameter>from</> points to
!        the first character of the string that is to be escaped, and the
!        <parameter>length</> parameter gives the number of bytes in this
!        string.  A terminating zero byte is not required, and should not be
!        counted in <parameter>length</>.  (If a terminating zero byte is found
!        before <parameter>length</> bytes are processed,
!        <function>PQescapeStringConn</> stops at the zero; the behavior is
!        thus rather like <function>strncpy</>.) <parameter>to</> shall point
!        to a buffer that is able to hold at least one more byte than twice
!        the value of <parameter>length</>, otherwise the behavior is undefined.
!        Behavior is likewise undefined if the <parameter>to</> and
!        <parameter>from</> strings overlap.
!       </para>
  
!       <para>
!        If the <parameter>error</> parameter is not NULL, then
!        <literal>*error</> is set to zero on success, nonzero on error.
!        Presently the only possible error conditions involve invalid multibyte
!        encoding in the source string.  The output string is still generated
!        on error, but it can be expected that the server will reject it as
!        malformed.  On error, a suitable message is stored in the
!        <parameter>conn</> object, whether or not <parameter>error</> is NULL.
!       </para>
  
!       <para>
!        <function>PQescapeStringConn</> returns the number of bytes written
!        to <parameter>to</>, not including the terminating zero byte.
!       </para>
!      </listitem>
!     </varlistentry>
  
!     <varlistentry>
!      <term>
!       <function>PQescapeString</function>
!       <indexterm>
!        <primary>PQescapeString</primary>
!       </indexterm>
!      </term>
  
!      <listitem>
!       <para>
!        <synopsis>
!        size_t PQescapeString (char *to, const char *from, size_t length);
!        </synopsis>
!       </para>
  
!       <para>
!        <function>PQescapeString</> is an older, deprecated version of
!        <function>PQescapeStringConn</>; the difference is that it does
!        not take <parameter>conn</> or <parameter>error</> parameters.
!        Because of this, it cannot adjust its behavior depending on the
!        connection properties (such as character encoding) and therefore
!        <emphasis>it might give the wrong results</>.  Also, it has no way
!        to report error conditions.
!       </para>
! 
!       <para>
!        <function>PQescapeString</> can be used safely in single-threaded
!        client programs that work with only one <productname>PostgreSQL</>
!        connection at a time (in this case it can find out what it needs to
!        know <quote>behind the scenes</>).  In other contexts it is a security
!        hazard and should be avoided in favor of
!        <function>PQescapeStringConn</>.
!       </para>
!      </listitem>
!     </varlistentry>
  
+     <varlistentry>
+      <term>
+       <function>PQescapeIdentConn</function>
+       <indexterm>
+        <primary>PQescapeIdentConn</primary>
+       </indexterm>
+      </term>
+ 
+      <listitem>
+       <para>
+        <synopsis>
+      void PQescapeIdentConn (PGconn *con, 
+     			     char *to, const char *from, 
+     			     int *error);
+        </synopsis>
+       </para>
+    
+       <para>
+        <function>PQescapeIdentConn</> writes an escaped string of the
+        <parameter>from</> string to the <parameter>to</>. Result is 
+        well formed SQL identifier. <parameter>to</> shall point to 
+        a buffer that is able to hold three bytes more than twice of
+        length string <parameter>from</>, otherwise the behavior is undefined.
+       </para>
+ 
+       <para>
+        If the <parameter>error</> parameter is not NULL, then
+        <literal>*error</> is set to zero on success, nonzero on error.
+        Presently the only possible error conditions involve invalid multibyte
+        encoding in the source string.  The output string is still generated
+        on error, but it can be expected that the server will reject it as
+        malformed.  On error, a suitable message is stored in the
+        <parameter>conn</> object, whether or not <parameter>error</> is NULL.
+       </para>
+ 
+      </listitem>
+     </varlistentry>
+    </variablelist>
+    
+   </sect2>
  
    <sect2 id="libpq-exec-escape-bytea">
     <title>Escaping Binary Strings for Inclusion in SQL Commands</title>
*** ./doc/src/sgml/ref/psql-ref.sgml.orig	2009-12-25 00:36:39.000000000 +0100
--- ./doc/src/sgml/ref/psql-ref.sgml	2010-01-04 10:45:39.350376804 +0100
***************
*** 2335,2340 ****
--- 2335,2361 ----
      </note>
  
      <para>
+     <application>psql</application> provides two additional syntax for 
+     retrieving the content of variable. This auxilary syntax ensure
+     necessary escaping when we would to use content as sql literal or
+     sql identifier.
+ <programlisting>
+ testdb=&gt; <userinput>\set foo 'hello world'</userinput>
+ testdb=&gt; <userinput>\echo :'foo'</userinput>
+ 'hello world'
+ 
+ testdb=&gt; <userinput>\echo :"foo"</userinput>
+ "hello world"
+ 
+ testdb=&gt; <userinput>SELECT :'foo' AS :"foo";</userinput>
+  hello world 
+  -------------
+  hello world
+ (1 row)
+ </programlisting>    
+     </para>
+ 
+     <para>
      If you call <command>\set</command> without a second argument, the
      variable is set, with an empty string as value. To unset (or delete) a
      variable, use the command <command>\unset</command>.
***************
*** 2722,2728 ****
      the variable is copied literally, so it can even contain unbalanced
      quotes or backslash commands. You must make sure that it makes sense
      where you put it. Variable interpolation will not be performed into
!     quoted <acronym>SQL</acronym> entities.
      </para>
  
      <para>
--- 2743,2755 ----
      the variable is copied literally, so it can even contain unbalanced
      quotes or backslash commands. You must make sure that it makes sense
      where you put it. Variable interpolation will not be performed into
!     quoted <acronym>SQL</acronym> entities. Identifiers with special chars
!     have to be inserted between double quotes. <application>psql</application>
!     ensure necessary quoting with additional syntax:
! <programlisting>
! testdb=&gt; <userinput>\set foo 'my tab'</userinput>
! testdb=&gt; <userinput>SELECT * FROM :"foo";</userinput>
! </programlisting>
      </para>
  
      <para>
***************
*** 2752,2757 ****
--- 2779,2793 ----
      at one point you thought it was great that all Unix commands use the
      same escape character.)
      </para>
+     
+     <para>
+     With alternative syntax for retrieving content of variables external
+     escaping are not necessary:
+ <programlisting>
+ testdb=&gt; <userinput>\set content `cat my_file.txt`</userinput>
+ testdb=&gt; <userinput>INSERT INTO my_table VALUES(:'content');</userinput>
+ </programlisting>
+     </para>
  
      <para>
      Since colons can legally appear in SQL commands, the following rule
*** ./src/bin/psql/psqlscan.l.orig	2010-01-02 17:57:59.000000000 +0100
--- ./src/bin/psql/psqlscan.l	2010-01-05 13:05:38.035047460 +0100
***************
*** 47,52 ****
--- 47,53 ----
  #include "settings.h"
  #include "variables.h"
  
+ #include "dumputils.h"
  
  /*
   * We use a stack of flex buffers to handle substitution of psql variables.
***************
*** 707,712 ****
--- 708,783 ----
  					}
  				}
  
+ :'[A-Za-z0-9_]+'	{
+ 					/* 
+ 					 * Possible psql variable substitution
+ 					 * with literal quoting.
+ 					 */
+ 					const char *value;
+ 
+ 					yytext[yyleng - 1] = '\0';
+ 					value = GetVariable(pset.vars, yytext + 2);
+ 
+ 					if (value)
+ 					{
+ 						/* It is a variable, perform substitution */
+ 						PQExpBufferData   buf;
+ 						
+ 						initPQExpBuffer(&buf);
+ 						appendStringLiteralConn(output_buf, value, pset.db);
+ 						push_new_buffer(buf.data);
+ 						termPQExpBuffer(&buf);
+ 						/* yy_scan_string already made buffer active */
+ 					}
+ 					else
+ 					{
+ 						/*
+ 						 * if the variable doesn't exist we'll copy the
+ 						 * string as is
+ 						 */
+ 						ECHO;
+ 					}
+ 				}
+ 
+ :\"[A-Za-z0-9_]+\"	{
+ 					/* Possible psql variable substitution with double quoting */
+ 					const char *value;
+ 
+ 					/* remove dquotes */
+ 					yytext[yyleng - 1] = '\0';
+ 					value = GetVariable(pset.vars, yytext + 2);
+ 
+ 					if (value)
+ 					{
+ 						int	error;
+ 						char    *identif;
+ 						
+ 						identif = pg_malloc(strlen(value) * 2 + 3);
+ 						PQescapeIdentConn(pset.db, identif, value, &error); 
+ 						
+ 						if (error)
+ 						{
+ 							const char *error_message = PQerrorMessage(pset.db);
+ 							
+ 							if (strlen(error_message))
+ 								psql_error("%s", error_message);
+ 						}
+ 						
+ 						push_new_buffer(identif);
+ 						free(identif);
+ 						/* yy_scan_string already made buffer active */
+ 					}
+ 					else
+ 					{
+ 						/*
+ 						 * if the variable doesn't exist we'll copy the
+ 						 * string as is
+ 						 */
+ 						ECHO;
+ 					}
+ 				}
+ 
+ 
  	/*
  	 * Back to backend-compatible rules.
  	 */
***************
*** 927,932 ****
--- 998,1067 ----
  					return LEXRES_OK;
  				}
  
+ :'[A-Za-z0-9_]*'	{
+ 					/* Possible psql variable substitution */
+ 					if (option_type == OT_VERBATIM)
+ 						ECHO;
+ 					else
+ 					{
+ 						const char *value;
+ 
+ 						yytext[yyleng - 1] = '\0';
+ 						value = GetVariable(pset.vars, yytext + 2);
+ 
+ 						/*
+ 						 * The variable value is just emitted without any
+ 						 * further examination.  This is consistent with the
+ 						 * pre-8.0 code behavior, if not with the way that
+ 						 * variables are handled outside backslash commands.
+ 						 */
+ 						if (value)
+ 							appendStringLiteralConn(output_buf, value, pset.db);
+ 					}
+ 
+ 					*option_quote = ':';
+ 
+ 					return LEXRES_OK;
+ 				}
+ 
+ :\"[A-Za-z0-9_]*\"	{
+ 					/* Possible psql variable substitution */
+ 					if (option_type == OT_VERBATIM)
+ 						ECHO;
+ 					else
+ 					{
+ 						const char *value;
+ 						
+ 						yytext[yyleng - 1] = '\0';
+ 						value = GetVariable(pset.vars, yytext + 2);
+ 
+ 						if (value)
+ 						{
+ 							int	error;
+ 							char    *identif;
+ 						
+ 							identif = pg_malloc(strlen(value) * 2 + 3);
+ 							PQescapeIdentConn(pset.db, identif, value, &error); 
+ 						
+ 							if (error)
+ 							{
+ 								const char *error_message = PQerrorMessage(pset.db);
+ 							
+ 								if (strlen(error_message))
+ 									psql_error("%s", error_message);
+ 							}
+ 						
+ 							appendPQExpBufferStr(output_buf, identif);
+ 							free(identif);
+ 						}
+ 					}
+ 
+ 					*option_quote = ':';
+ 
+ 					return LEXRES_OK;
+ 				}
+ 
+ 
  "|"				{
  					ECHO;
  					if (option_type == OT_FILEPIPE)
*** ./src/interfaces/libpq/exports.txt.orig	2009-03-31 03:41:27.000000000 +0200
--- ./src/interfaces/libpq/exports.txt	2010-01-04 10:57:06.934376931 +0100
***************
*** 153,155 ****
--- 153,156 ----
  PQfireResultCreateEvents  151
  PQconninfoParse           152
  PQinitOpenSSL             153
+ PQescapeIdentConn         154
*** ./src/interfaces/libpq/fe-exec.c.orig	2009-08-04 20:05:42.000000000 +0200
--- ./src/interfaces/libpq/fe-exec.c	2010-01-05 12:57:19.548047500 +0100
***************
*** 3,14 ****
   * fe-exec.c
   *	  functions related to sending a query down to the backend
   *
!  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   *
   * IDENTIFICATION
!  *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.205 2009/08/04 18:05:42 tgl Exp $
   *
   *-------------------------------------------------------------------------
   */
--- 3,14 ----
   * fe-exec.c
   *	  functions related to sending a query down to the backend
   *
!  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   *
   * IDENTIFICATION
!  *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.206 2010/01/02 16:58:12 momjian Exp $
   *
   *-------------------------------------------------------------------------
   */
***************
*** 3345,3347 ****
--- 3345,3424 ----
  	*retbuflen = buflen;
  	return tmpbuf;
  }
+ 
+ /*
+  * PQescapeIdentConn - returns valid SQL identifier. 
+  *
+  *   Replace " by "" and insert strings to pair of double quotes.
+  *
+  */
+ void
+ PQescapeIdentConn(PGconn *conn, char *to, const char *source, int *error)
+ {
+ 	if (!conn)
+ 	{
+ 		/* force empty-string result */
+ 		*to = '\0';
+ 		if (*error)
+ 			*error = 1;
+ 		return;
+ 	}
+ 	
+ 	*to++ = '"';
+ 	
+ 	while (*source != '\0')
+ 	{
+ 		char 		c = *source;
+ 		int			len;
+ 		int			i;
+ 		
+ 		/* Fast path for plain ASCII */
+ 		if (!IS_HIGHBIT_SET(c))
+ 		{
+ 			if (c == '"')
+ 				*to++ = c;
+ 			*to++ = c;
+ 			source++;
+ 			continue;
+ 		}
+ 	
+ 		/* Slow path for possible multibyte characters */
+ 		len = pg_encoding_mblen(conn->client_encoding, source);
+ 
+ 		/* Copy the character */
+ 		for (i = 0; i < len; i++)
+ 		{
+ 			if (*source == '\0')
+ 				break;
+ 			*to++ = *source++;
+ 		}
+ 
+ 		/*
+ 		 * If we hit premature end of string (ie, incomplete multibyte
+ 		 * character), try to pad out to the correct length with spaces. We
+ 		 * may not be able to pad completely, but we will always be able to
+ 		 * insert at least one pad space (since we'd not have quoted a
+ 		 * multibyte character).  This should be enough to make a string that
+ 		 * the server will error out on.
+ 		 */
+ 		if (i < len)
+ 		{
+ 			if (error)
+ 				*error = 1;
+ 			if (conn)
+ 				printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("incomplete multibyte character\n"));
+ 			for (; i < len; i++)
+ 				*to++ = ' ';
+ 
+ 			break;
+ 		}
+ 	}
+ 
+ 	*to++ = '"';
+ 
+ 	/* Write the terminating NUL character. */
+ 	*to = '\0';
+ 
+ 	return;
+ }
*** ./src/interfaces/libpq/libpq-fe.h.orig	2009-06-11 16:49:14.000000000 +0200
--- ./src/interfaces/libpq/libpq-fe.h	2010-01-05 12:57:37.688923153 +0100
***************
*** 4,13 ****
   *	  This file contains definitions for structures and
   *	  externs for functions used by frontend postgres applications.
   *
!  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
!  * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.147 2009/06/11 14:49:14 momjian Exp $
   *
   *-------------------------------------------------------------------------
   */
--- 4,13 ----
   *	  This file contains definitions for structures and
   *	  externs for functions used by frontend postgres applications.
   *
!  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
!  * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.148 2010/01/02 16:58:12 momjian Exp $
   *
   *-------------------------------------------------------------------------
   */
***************
*** 476,481 ****
--- 476,482 ----
  				  size_t *to_length);
  extern unsigned char *PQunescapeBytea(const unsigned char *strtext,
  				size_t *retbuflen);
+ extern void PQescapeIdentConn(PGconn *conn, char *to, const char *source, int *error);
  
  /* These forms are deprecated! */
  extern size_t PQescapeString(char *to, const char *from, size_t length);
