]> granicus.if.org Git - postgresql/commitdiff
Add support for \x hex escapes in COPY.
authorBruce Momjian <bruce@momjian.us>
Thu, 2 Jun 2005 01:21:22 +0000 (01:21 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 2 Jun 2005 01:21:22 +0000 (01:21 +0000)
Sergey Ten

doc/src/sgml/ref/copy.sgml
src/backend/commands/copy.c

index 0dd10d6754d1a5b49088e73ddf8fcb4876eb61c5..188f892fa0f495a42caaf327fd51a667b7999f00 100644 (file)
@@ -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>
index 35ae86814dcfc82574dafa1b061dd6ffdcdeede9..30eeefded8e4e1d6deeafb72a59208e64d644ecf 100644 (file)
@@ -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;