diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/nodes/outfuncs.c | 21 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 14 |
2 files changed, 30 insertions, 5 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 24ea0487e7f..63dda75ae52 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -135,16 +135,23 @@ static void outChar(StringInfo str, char c); * Convert an ordinary string (eg, an identifier) into a form that * will be decoded back to a plain token by read.c's functions. * - * If a null or empty string is given, it is encoded as "<>". + * If a null string pointer is given, it is encoded as '<>'. + * An empty string is encoded as '""'. To avoid ambiguity, input + * strings beginning with '<' or '"' receive a leading backslash. */ void outToken(StringInfo str, const char *s) { - if (s == NULL || *s == '\0') + if (s == NULL) { appendStringInfoString(str, "<>"); return; } + if (*s == '\0') + { + appendStringInfoString(str, "\"\""); + return; + } /* * Look for characters or patterns that are treated specially by read.c @@ -178,6 +185,13 @@ outChar(StringInfo str, char c) { char in[2]; + /* Traditionally, we've represented \0 as <>, so keep doing that */ + if (c == '\0') + { + appendStringInfoString(str, "<>"); + return; + } + in[0] = c; in[1] = '\0'; @@ -636,7 +650,8 @@ _outString(StringInfo str, const String *node) { /* * We use outToken to provide escaping of the string's content, but we - * don't want it to do anything with an empty string. + * don't want it to convert an empty string to '""', because we're putting + * double quotes around the string already. */ appendStringInfoChar(str, '"'); if (node->sval[0] != '\0') diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 89a9a50f7cb..b4ff855f7c6 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -178,8 +178,18 @@ #define strtobool(x) ((*(x) == 't') ? true : false) -#define nullable_string(token,length) \ - ((length) == 0 ? NULL : debackslash(token, length)) +static char * +nullable_string(const char *token, int length) +{ + /* outToken emits <> for NULL, and pg_strtok makes that an empty string */ + if (length == 0) + return NULL; + /* outToken emits "" for empty string */ + if (length == 2 && token[0] == '"' && token[1] == '"') + return pstrdup(""); + /* otherwise, we must remove protective backslashes added by outToken */ + return debackslash(token, length); +} /* |