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