Index: doc/src/sgml/ref/copy.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v retrieving revision 1.65 diff -c -c -r1.65 copy.sgml *** doc/src/sgml/ref/copy.sgml 7 May 2005 02:22:45 -0000 1.65 --- doc/src/sgml/ref/copy.sgml 28 May 2005 03:49:10 -0000 *************** *** 424,436 **** Backslash followed by one to three octal digits specifies the character with that numeric code ! Presently, COPY TO will never emit an octal-digits ! backslash sequence, but it does use the other sequences listed above ! for those control characters. --- 424,441 ---- Backslash followed by one to three octal digits specifies the character with that numeric code + + \xdigits + Backslash x followed by one or two hex digits specifies + the character with that numeric code + ! Presently, COPY TO will never emit an octal or ! hex-digits backslash sequence, but it does use the other sequences ! listed above for those control characters. Index: src/backend/commands/copy.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/copy.c,v retrieving revision 1.244 diff -c -c -r1.244 copy.c *** src/backend/commands/copy.c 7 May 2005 02:22:46 -0000 1.244 --- src/backend/commands/copy.c 28 May 2005 03:49:12 -0000 *************** *** 2274,2279 **** --- 2274,2294 ---- return result; } + /* + * Return decimal value for a hexadecimal digit + */ + static + int GetDecimalFromHex(char hex) + { + if (isdigit(hex)) + return hex - '0'; + else + { + hex = tolower(hex); + return hex - 'a' + 10; + } + } + /*---------- * Read the value of a single attribute, performing de-escaping as needed. * *************** *** 2335,2340 **** --- 2350,2356 ---- case '5': case '6': case '7': + /* handle \013 */ { int val; *************** *** 2360,2365 **** --- 2376,2405 ---- 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;