Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4343c0e

Browse files
committed
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.
1 parent e8bf683 commit 4343c0e

File tree

6 files changed

+75
-62
lines changed

6 files changed

+75
-62
lines changed

contrib/dblink/dblink.c

-20
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ static char **get_text_array_contents(ArrayType *array, int *numitems);
9191
static char *get_sql_insert(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
9292
static char *get_sql_delete(Relation rel, int *pkattnums, int pknumatts, char **tgt_pkattvals);
9393
static char *get_sql_update(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
94-
static char *quote_literal_cstr(char *rawstr);
9594
static char *quote_ident_cstr(char *rawstr);
9695
static int get_attnum_pk_pos(int *pkattnums, int pknumatts, int key);
9796
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
18931892
return (buf.data);
18941893
}
18951894

1896-
/*
1897-
* Return a properly quoted literal value.
1898-
* Uses quote_literal in quote.c
1899-
*/
1900-
static char *
1901-
quote_literal_cstr(char *rawstr)
1902-
{
1903-
text *rawstr_text;
1904-
text *result_text;
1905-
char *result;
1906-
1907-
rawstr_text = cstring_to_text(rawstr);
1908-
result_text = DatumGetTextP(DirectFunctionCall1(quote_literal,
1909-
PointerGetDatum(rawstr_text)));
1910-
result = text_to_cstring(result_text);
1911-
1912-
return result;
1913-
}
1914-
19151895
/*
19161896
* Return a properly quoted identifier.
19171897
* Uses quote_ident in quote.c

contrib/tablefunc/tablefunc.c

-20
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ static Tuplestorestate *build_tuplestore_recursively(char *key_fld,
8585
MemoryContext per_query_ctx,
8686
AttInMetadata *attinmeta,
8787
Tuplestorestate *tupstore);
88-
static char *quote_literal_cstr(char *rawstr);
8988

9089
typedef struct
9190
{
@@ -1564,22 +1563,3 @@ compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
15641563
/* OK, the two tupdescs are compatible for our purposes */
15651564
return true;
15661565
}
1567-
1568-
/*
1569-
* Return a properly quoted literal value.
1570-
* Uses quote_literal in quote.c
1571-
*/
1572-
static char *
1573-
quote_literal_cstr(char *rawstr)
1574-
{
1575-
text *rawstr_text;
1576-
text *result_text;
1577-
char *result;
1578-
1579-
rawstr_text = cstring_to_text(rawstr);
1580-
result_text = DatumGetTextP(DirectFunctionCall1(quote_literal,
1581-
PointerGetDatum(rawstr_text)));
1582-
result = text_to_cstring(result_text);
1583-
1584-
return result;
1585-
}

src/backend/utils/adt/quote.c

+53-22
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,46 @@ quote_ident(PG_FUNCTION_ARGS)
3333
}
3434

3535
/*
36-
* quote_literal -
37-
* returns a properly quoted literal
36+
* quote_literal_internal -
37+
* helper function for quote_literal and quote_literal_cstr
3838
*
3939
* NOTE: think not to make this function's behavior change with
4040
* standard_conforming_strings. We don't know where the result
4141
* literal will be used, and so we must generate a result that
4242
* will work with either setting. Take a look at what dblink
4343
* uses this for before thinking you know better.
4444
*/
45+
static size_t
46+
quote_literal_internal(char *dst, char *src, size_t len)
47+
{
48+
char *s;
49+
char *savedst = dst;
50+
51+
for (s = src; s < src + len; s++)
52+
{
53+
if (*s == '\\')
54+
{
55+
*dst++ = ESCAPE_STRING_SYNTAX;
56+
break;
57+
}
58+
}
59+
60+
*dst++ = '\'';
61+
while (len-- > 0)
62+
{
63+
if (SQL_STR_DOUBLE(*src, true))
64+
*dst++ = *src;
65+
*dst++ = *src++;
66+
}
67+
*dst++ = '\'';
68+
69+
return dst - savedst;
70+
}
71+
72+
/*
73+
* quote_literal -
74+
* returns a properly quoted literal
75+
*/
4576
Datum
4677
quote_literal(PG_FUNCTION_ARGS)
4778
{
@@ -58,30 +89,30 @@ quote_literal(PG_FUNCTION_ARGS)
5889
cp1 = VARDATA(t);
5990
cp2 = VARDATA(result);
6091

61-
for (; len-- > 0; cp1++)
62-
{
63-
if (*cp1 == '\\')
64-
{
65-
*cp2++ = ESCAPE_STRING_SYNTAX;
66-
break;
67-
}
68-
}
92+
SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
6993

70-
len = VARSIZE(t) - VARHDRSZ;
71-
cp1 = VARDATA(t);
94+
PG_RETURN_TEXT_P(result);
95+
}
7296

73-
*cp2++ = '\'';
74-
while (len-- > 0)
75-
{
76-
if (SQL_STR_DOUBLE(*cp1, true))
77-
*cp2++ = *cp1;
78-
*cp2++ = *cp1++;
79-
}
80-
*cp2++ = '\'';
97+
/*
98+
* quote_literal_cstr -
99+
* returns a properly quoted literal
100+
*/
101+
char *
102+
quote_literal_cstr(char *rawstr)
103+
{
104+
char *result;
105+
int len;
106+
int newlen;
81107

82-
SET_VARSIZE(result, cp2 - ((char *) result));
108+
len = strlen(rawstr);
109+
/* We make a worst-case result area; wasting a little space is OK */
110+
result = palloc(len * 2 + 3);
83111

84-
PG_RETURN_TEXT_P(result);
112+
newlen = quote_literal_internal(result, rawstr, len);
113+
result[newlen] = '\0';
114+
115+
return result;
85116
}
86117

87118
/*

src/include/utils/builtins.h

+1
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,7 @@ extern int32 type_maximum_size(Oid type_oid, int32 typemod);
977977
/* quote.c */
978978
extern Datum quote_ident(PG_FUNCTION_ARGS);
979979
extern Datum quote_literal(PG_FUNCTION_ARGS);
980+
extern char *quote_literal_cstr(char *rawstr);
980981
extern Datum quote_nullable(PG_FUNCTION_ARGS);
981982

982983
/* guc.c */

src/test/regress/expected/text.out

+18
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,21 @@ select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) ord
118118
5 | ahoj | ahoj
119119
(11 rows)
120120

121+
select quote_literal('');
122+
quote_literal
123+
---------------
124+
''
125+
(1 row)
126+
127+
select quote_literal('abc''');
128+
quote_literal
129+
---------------
130+
'abc'''
131+
(1 row)
132+
133+
select quote_literal(e'\\');
134+
quote_literal
135+
---------------
136+
E'\\'
137+
(1 row)
138+

src/test/regress/sql/text.sql

+3
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,6 @@ select concat_ws('',10,20,null,30);
4141
select concat_ws(NULL,10,20,null,30) is null;
4242
select reverse('abcde');
4343
select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) order by i;
44+
select quote_literal('');
45+
select quote_literal('abc''');
46+
select quote_literal(e'\\');

0 commit comments

Comments
 (0)