diff options
author | Jan Wieck <JanWieck@Yahoo.com> | 2000-09-05 20:25:14 +0000 |
---|---|---|
committer | Jan Wieck <JanWieck@Yahoo.com> | 2000-09-05 20:25:14 +0000 |
commit | daf1e3a7026e367d630be3ac34ac0a9e7cf1340f (patch) | |
tree | 88420f149500bb3205f390fc7e3c42907e0e66b9 /src/backend/utils/adt/quote.c | |
parent | d7f1e110267de738499ec6dc8b7cf6443e8c3a67 (diff) | |
download | postgresql-daf1e3a7026e367d630be3ac34ac0a9e7cf1340f.tar.gz postgresql-daf1e3a7026e367d630be3ac34ac0a9e7cf1340f.zip |
Added functions
quote_ident(text) returns text
quote_literal(text) returns text
These are handy to build up properly quoted query strings
for the new PL/pgSQL EXECUTE functionality to submit
dynamic DDL statements.
Jan
Diffstat (limited to 'src/backend/utils/adt/quote.c')
-rw-r--r-- | src/backend/utils/adt/quote.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c new file mode 100644 index 00000000000..aaa4aaaa1b8 --- /dev/null +++ b/src/backend/utils/adt/quote.c @@ -0,0 +1,291 @@ +/*------------------------------------------------------------------------- + * + * quote.c + * Functions for quoting identifiers and literals + * + * Portions Copyright (c) 2000, PostgreSQL, Inc + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/utils/adt/quote.c,v 1.1 2000/09/05 20:25:13 wieck Exp $ + * + *------------------------------------------------------------------------- + */ +#include <ctype.h> + +#include "postgres.h" + +#include "mb/pg_wchar.h" +#include "utils/builtins.h" + + +static bool quote_ident_required(text *iptr); +static text *do_quote_ident(text *iptr); +static text *do_quote_literal(text *iptr); + + +/* + * quote_ident - + * returns a properly quoted identifier + */ +Datum +quote_ident(PG_FUNCTION_ARGS) +{ + text *t = PG_GETARG_TEXT_P(0); + text *result; + + if (quote_ident_required(t)) + { + result = do_quote_ident(t); + } + else + { + result = (text *)palloc(VARSIZE(t)); + memcpy(result, t, VARSIZE(t)); + } + + PG_FREE_IF_COPY(t, 0); + + return result; +} + +/* + * quote_literal - + * returns a properly quoted literal + */ +Datum +quote_literal(PG_FUNCTION_ARGS) +{ + text *t = PG_GETARG_TEXT_P(0); + text *result; + + result = do_quote_literal(t); + + PG_FREE_IF_COPY(t, 0); + + return result; +} + + +/* + * MULTIBYTE dependant internal functions follow + * + */ + + +#ifndef MULTIBYTE + +/* Check if a given identifier needs quoting */ +static bool +quote_ident_required(text *iptr) +{ + char *cp; + char *ep; + + cp = VARDATA(iptr); + ep = VARDATA(iptr) + VARSIZE(iptr) - VARHDRSZ; + + if (cp >= ep) + return true; + + if (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z'))) + return true; + + while((++cp) < ep) + { + if (*cp >= 'a' && *cp <= 'z') continue; + if (*cp >= '0' && *cp <= '9') continue; + if (*cp == '_') continue; + + return true; + } + + return false; +} + +/* Return a properly quoted identifier */ +static text * +do_quote_ident(text *iptr) +{ + text *result; + char *cp1; + char *cp2; + int len; + + len = VARSIZE(iptr) - VARHDRSZ; + result = (text *)palloc(len * 2 + VARHDRSZ + 2); + + cp1 = VARDATA(iptr); + cp2 = VARDATA(result); + + *cp2++ = '"'; + while(len-- > 0) + { + if (*cp1 == '"') + *cp2++ = '"'; + if (*cp1 == '\\') + *cp2++ = '\\'; + *cp2++ = *cp1++; + } + *cp2++ = '"'; + + VARATT_SIZEP(result) = cp2 - ((char *)result); + + return result; +} + +/* Return a properly quoted literal value */ +static text * +do_quote_literal(text *lptr) +{ + text *result; + char *cp1; + char *cp2; + int len; + + len = VARSIZE(lptr) - VARHDRSZ; + result = (text *)palloc(len * 2 + VARHDRSZ + 2); + + cp1 = VARDATA(lptr); + cp2 = VARDATA(result); + + *cp2++ = '\''; + while(len-- > 0) + { + if (*cp1 == '\'') + *cp2++ = '\''; + if (*cp1 == '\\') + *cp2++ = '\\'; + *cp2++ = *cp1++; + } + *cp2++ = '\''; + + VARATT_SIZEP(result) = cp2 - ((char *)result); + + return result; +} + +#else + +/* Check if a given identifier needs quoting (MULTIBYTE version) */ +static bool +quote_ident_required(text *iptr) +{ + char *cp; + char *ep; + + cp = VARDATA(iptr); + ep = VARDATA(iptr) + VARSIZE(iptr) - VARHDRSZ; + + if (cp >= ep) + return true; + + if(pg_mblen(cp) != 1) + return true; + if (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z'))) + return true; + + while((++cp) < ep) + { + if (pg_mblen(cp) != 1) + return true; + + if (*cp >= 'a' && *cp <= 'z') continue; + if (*cp >= '0' && *cp <= '9') continue; + if (*cp == '_') continue; + + return true; + } + + return false; +} + +/* Return a properly quoted identifier (MULTIBYTE version) */ +static text * +do_quote_ident(text *iptr) +{ + text *result; + char *cp1; + char *cp2; + int len; + int wl; + + len = VARSIZE(iptr) - VARHDRSZ; + result = (text *)palloc(len * 2 + VARHDRSZ + 2); + + cp1 = VARDATA(iptr); + cp2 = VARDATA(result); + + *cp2++ = '"'; + while(len > 0) + { + if ((wl = pg_mblen(cp1)) != 1) + { + len -= wl; + + while(wl-- > 0) + *cp2++ = *cp1++; + continue; + } + + if (*cp1 == '"') + *cp2++ = '"'; + if (*cp1 == '\\') + *cp2++ = '\\'; + *cp2++ = *cp1++; + + len--; + } + *cp2++ = '"'; + + VARATT_SIZEP(result) = cp2 - ((char *)result); + + return result; +} + +/* Return a properly quoted literal value (MULTIBYTE version) */ +static text * +do_quote_literal(text *lptr) +{ + text *result; + char *cp1; + char *cp2; + int len; + int wl; + + len = VARSIZE(lptr) - VARHDRSZ; + result = (text *)palloc(len * 2 + VARHDRSZ + 2); + + cp1 = VARDATA(lptr); + cp2 = VARDATA(result); + + *cp2++ = '\''; + while(len > 0) + { + if ((wl = pg_mblen(cp1)) != 1) + { + len -= wl; + + while(wl-- > 0) + *cp2++ = *cp1++; + continue; + } + + if (*cp1 == '\'') + *cp2++ = '\''; + if (*cp1 == '\\') + *cp2++ = '\\'; + *cp2++ = *cp1++; + + len--; + } + *cp2++ = '\''; + + VARATT_SIZEP(result) = cp2 - ((char *)result); + + return result; +} + +#endif + + |