diff options
author | Robert Haas <rhaas@postgresql.org> | 2010-11-20 10:04:48 -0500 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2010-11-20 10:04:48 -0500 |
commit | 4343c0e546b216ab38a3397a4f0f7476d557b352 (patch) | |
tree | 5a5676ac12ebe9f480851e2bb963ac1418c86921 /src | |
parent | e8bf683fbee935181e207d7171630194ed01f6a1 (diff) | |
download | postgresql-4343c0e546b216ab38a3397a4f0f7476d557b352.tar.gz postgresql-4343c0e546b216ab38a3397a4f0f7476d557b352.zip |
Expose quote_literal_cstr() from core.
This eliminates the need for inefficient implementions of this
functionality in both contrib/dblink and contrib/tablefunc, so remove
them. The upcoming patch implementing an in-core format() function
will also require this functionality.
In passing, add some regression tests.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/quote.c | 75 | ||||
-rw-r--r-- | src/include/utils/builtins.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/text.out | 18 | ||||
-rw-r--r-- | src/test/regress/sql/text.sql | 3 |
4 files changed, 75 insertions, 22 deletions
diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c index 70e98cad84b..af07443f7df 100644 --- a/src/backend/utils/adt/quote.c +++ b/src/backend/utils/adt/quote.c @@ -33,8 +33,8 @@ quote_ident(PG_FUNCTION_ARGS) } /* - * quote_literal - - * returns a properly quoted literal + * quote_literal_internal - + * helper function for quote_literal and quote_literal_cstr * * NOTE: think not to make this function's behavior change with * standard_conforming_strings. We don't know where the result @@ -42,6 +42,37 @@ quote_ident(PG_FUNCTION_ARGS) * will work with either setting. Take a look at what dblink * uses this for before thinking you know better. */ +static size_t +quote_literal_internal(char *dst, char *src, size_t len) +{ + char *s; + char *savedst = dst; + + for (s = src; s < src + len; s++) + { + if (*s == '\\') + { + *dst++ = ESCAPE_STRING_SYNTAX; + break; + } + } + + *dst++ = '\''; + while (len-- > 0) + { + if (SQL_STR_DOUBLE(*src, true)) + *dst++ = *src; + *dst++ = *src++; + } + *dst++ = '\''; + + return dst - savedst; +} + +/* + * quote_literal - + * returns a properly quoted literal + */ Datum quote_literal(PG_FUNCTION_ARGS) { @@ -58,30 +89,30 @@ quote_literal(PG_FUNCTION_ARGS) cp1 = VARDATA(t); cp2 = VARDATA(result); - for (; len-- > 0; cp1++) - { - if (*cp1 == '\\') - { - *cp2++ = ESCAPE_STRING_SYNTAX; - break; - } - } + SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len)); - len = VARSIZE(t) - VARHDRSZ; - cp1 = VARDATA(t); + PG_RETURN_TEXT_P(result); +} - *cp2++ = '\''; - while (len-- > 0) - { - if (SQL_STR_DOUBLE(*cp1, true)) - *cp2++ = *cp1; - *cp2++ = *cp1++; - } - *cp2++ = '\''; +/* + * quote_literal_cstr - + * returns a properly quoted literal + */ +char * +quote_literal_cstr(char *rawstr) +{ + char *result; + int len; + int newlen; - SET_VARSIZE(result, cp2 - ((char *) result)); + len = strlen(rawstr); + /* We make a worst-case result area; wasting a little space is OK */ + result = palloc(len * 2 + 3); - PG_RETURN_TEXT_P(result); + newlen = quote_literal_internal(result, rawstr, len); + result[newlen] = '\0'; + + return result; } /* diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 7b1bb235383..ae267ab17ad 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -977,6 +977,7 @@ extern int32 type_maximum_size(Oid type_oid, int32 typemod); /* quote.c */ extern Datum quote_ident(PG_FUNCTION_ARGS); extern Datum quote_literal(PG_FUNCTION_ARGS); +extern char *quote_literal_cstr(char *rawstr); extern Datum quote_nullable(PG_FUNCTION_ARGS); /* guc.c */ diff --git a/src/test/regress/expected/text.out b/src/test/regress/expected/text.out index 84f4a5cda8b..0b0014a6e25 100644 --- a/src/test/regress/expected/text.out +++ b/src/test/regress/expected/text.out @@ -118,3 +118,21 @@ select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) ord 5 | ahoj | ahoj (11 rows) +select quote_literal(''); + quote_literal +--------------- + '' +(1 row) + +select quote_literal('abc'''); + quote_literal +--------------- + 'abc''' +(1 row) + +select quote_literal(e'\\'); + quote_literal +--------------- + E'\\' +(1 row) + diff --git a/src/test/regress/sql/text.sql b/src/test/regress/sql/text.sql index a8768ee81aa..50c3033d9eb 100644 --- a/src/test/regress/sql/text.sql +++ b/src/test/regress/sql/text.sql @@ -41,3 +41,6 @@ select concat_ws('',10,20,null,30); select concat_ws(NULL,10,20,null,30) is null; select reverse('abcde'); select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) order by i; +select quote_literal(''); +select quote_literal('abc'''); +select quote_literal(e'\\'); |