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.
This commit is contained in:
Robert Haas 2010-11-20 10:04:48 -05:00
parent e8bf683fbe
commit 4343c0e546
6 changed files with 77 additions and 64 deletions

View file

@ -91,7 +91,6 @@ static char **get_text_array_contents(ArrayType *array, int *numitems);
static char *get_sql_insert(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
static char *get_sql_delete(Relation rel, int *pkattnums, int pknumatts, char **tgt_pkattvals);
static char *get_sql_update(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
static char *quote_literal_cstr(char *rawstr);
static char *quote_ident_cstr(char *rawstr);
static int get_attnum_pk_pos(int *pkattnums, int pknumatts, int key);
static HeapTuple get_tuple_of_interest(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals);
@ -1893,25 +1892,6 @@ get_sql_update(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals
return (buf.data);
}
/*
* Return a properly quoted literal value.
* Uses quote_literal in quote.c
*/
static char *
quote_literal_cstr(char *rawstr)
{
text *rawstr_text;
text *result_text;
char *result;
rawstr_text = cstring_to_text(rawstr);
result_text = DatumGetTextP(DirectFunctionCall1(quote_literal,
PointerGetDatum(rawstr_text)));
result = text_to_cstring(result_text);
return result;
}
/*
* Return a properly quoted identifier.
* Uses quote_ident in quote.c

View file

@ -85,7 +85,6 @@ static Tuplestorestate *build_tuplestore_recursively(char *key_fld,
MemoryContext per_query_ctx,
AttInMetadata *attinmeta,
Tuplestorestate *tupstore);
static char *quote_literal_cstr(char *rawstr);
typedef struct
{
@ -1564,22 +1563,3 @@ compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
/* OK, the two tupdescs are compatible for our purposes */
return true;
}
/*
* Return a properly quoted literal value.
* Uses quote_literal in quote.c
*/
static char *
quote_literal_cstr(char *rawstr)
{
text *rawstr_text;
text *result_text;
char *result;
rawstr_text = cstring_to_text(rawstr);
result_text = DatumGetTextP(DirectFunctionCall1(quote_literal,
PointerGetDatum(rawstr_text)));
result = text_to_cstring(result_text);
return result;
}

View file

@ -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,32 +89,32 @@ quote_literal(PG_FUNCTION_ARGS)
cp1 = VARDATA(t);
cp2 = VARDATA(result);
for (; len-- > 0; cp1++)
{
if (*cp1 == '\\')
{
*cp2++ = ESCAPE_STRING_SYNTAX;
break;
}
}
len = VARSIZE(t) - VARHDRSZ;
cp1 = VARDATA(t);
*cp2++ = '\'';
while (len-- > 0)
{
if (SQL_STR_DOUBLE(*cp1, true))
*cp2++ = *cp1;
*cp2++ = *cp1++;
}
*cp2++ = '\'';
SET_VARSIZE(result, cp2 - ((char *) result));
SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
PG_RETURN_TEXT_P(result);
}
/*
* quote_literal_cstr -
* returns a properly quoted literal
*/
char *
quote_literal_cstr(char *rawstr)
{
char *result;
int len;
int newlen;
len = strlen(rawstr);
/* We make a worst-case result area; wasting a little space is OK */
result = palloc(len * 2 + 3);
newlen = quote_literal_internal(result, rawstr, len);
result[newlen] = '\0';
return result;
}
/*
* quote_nullable -
* Returns a properly quoted literal, with null values returned

View file

@ -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 */

View file

@ -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)

View file

@ -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'\\');