diff options
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 78cb6306e02..88528b9a065 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.104 2002/05/12 23:43:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.105 2002/05/17 01:19:18 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -2576,27 +2576,33 @@ quote_identifier(const char *ident) * and contains only lowercase letters, digits, and underscores, *and* is * not any SQL keyword. Otherwise, supply quotes. */ + int nquotes = 0; bool safe; + const char *ptr; char *result; + char *optr; /* * would like to use <ctype.h> macros here, but they might yield * unwanted locale-specific results... */ safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_'); - if (safe) + + for (ptr = ident; *ptr; ptr++) { - const char *ptr; + char ch = *ptr; - for (ptr = ident + 1; *ptr; ptr++) + if ((ch >= 'a' && ch <= 'z') || + (ch >= '0' && ch <= '9') || + (ch == '_')) { - char ch = *ptr; - - safe = ((ch >= 'a' && ch <= 'z') || - (ch >= '0' && ch <= '9') || - (ch == '_')); - if (!safe) - break; + /* okay */ + } + else + { + safe = false; + if (ch == '"') + nquotes++; } } @@ -2618,8 +2624,21 @@ quote_identifier(const char *ident) if (safe) return ident; /* no change needed */ - result = (char *) palloc(strlen(ident) + 2 + 1); - sprintf(result, "\"%s\"", ident); + result = (char *) palloc(strlen(ident) + nquotes + 2 + 1); + + optr = result; + *optr++ = '"'; + for (ptr = ident; *ptr; ptr++) + { + char ch = *ptr; + + if (ch == '"') + *optr++ = '"'; + *optr++ = ch; + } + *optr++ = '"'; + *optr = '\0'; + return result; } |