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

Lines changed: 0 additions & 20 deletions
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

Lines changed: 0 additions & 20 deletions
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

Lines changed: 53 additions & 22 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 18 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy