From 202e6e73e6947b9c8baf9c8758618c1d8a5dcd73 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Thu, 2 Jun 2005 01:21:22 +0000
Subject: [PATCH] Add support for \x hex escapes in COPY.

Sergey Ten
---
 doc/src/sgml/ref/copy.sgml  | 13 +++++++++----
 src/backend/commands/copy.c | 39 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 0dd10d6754d..188f892fa0f 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.65 2005/05/07 02:22:45 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.66 2005/06/02 01:21:21 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -424,13 +424,18 @@ COPY <replaceable class="parameter">tablename</replaceable> [ ( <replaceable cla
        <entry>Backslash followed by one to three octal digits specifies
        the character with that numeric code</entry>
       </row>
+      <row>
+       <entry><literal>\x</><replaceable>digits</></entry>
+       <entry>Backslash <literal>x</> followed by one or two hex digits specifies
+       the character with that numeric code</entry>
+      </row>
      </tbody>
     </tgroup>
    </informaltable>
 
-    Presently, <command>COPY TO</command> will never emit an octal-digits
-    backslash sequence, but it does use the other sequences listed above
-    for those control characters.
+    Presently, <command>COPY TO</command> will never emit an octal or 
+    hex-digits backslash sequence, but it does use the other sequences
+    listed above for those control characters.
    </para>
 
    <para>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 35ae86814dc..30eeefded8e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.244 2005/05/07 02:22:46 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.245 2005/06/02 01:21:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2274,6 +2274,18 @@ CopyReadLine(char * quote, char * escape)
 	return result;
 }
 
+/*
+ *	Return decimal value for a hexadecimal digit
+ */
+static
+int GetDecimalFromHex(char hex)
+{
+	if (isdigit(hex))
+		return hex - '0';
+	else
+		return tolower(hex) - 'a' + 10;
+}
+
 /*----------
  * Read the value of a single attribute, performing de-escaping as needed.
  *
@@ -2335,6 +2347,7 @@ CopyReadAttribute(const char *delim, const char *null_print,
 				case '5':
 				case '6':
 				case '7':
+					/* handle \013 */
 					{
 						int			val;
 
@@ -2360,6 +2373,30 @@ CopyReadAttribute(const char *delim, const char *null_print,
 						c = val & 0377;
 					}
 					break;
+				case 'x':
+					/* Handle \x3F */
+					if (line_buf.cursor < line_buf.len)
+					{
+						char hexchar = line_buf.data[line_buf.cursor];
+
+						if (isxdigit(hexchar))
+						{
+							int val = GetDecimalFromHex(hexchar);
+
+							line_buf.cursor++;
+							if (line_buf.cursor < line_buf.len)
+							{
+								hexchar = line_buf.data[line_buf.cursor];
+								if (isxdigit(hexchar))
+								{
+									line_buf.cursor++;
+									val = (val << 4) + GetDecimalFromHex(hexchar);
+								}
+							}
+							c = val & 0xff;
+						}
+					}
+					break;
 				case 'b':
 					c = '\b';
 					break;
-- 
GitLab