1/*-------------------------------------------------------------------------
2 *
3 * quote.c
4 * Functions for quoting identifiers and literals
5 *
6 * Portions Copyright (c) 2000-2019, PostgreSQL Global Development Group
7 *
8 *
9 * IDENTIFICATION
10 * src/backend/utils/adt/quote.c
11 *
12 *-------------------------------------------------------------------------
13 */
14#include "postgres.h"
15
16#include "utils/builtins.h"
17
18
19/*
20 * quote_ident -
21 * returns a properly quoted identifier
22 */
23Datum
24quote_ident(PG_FUNCTION_ARGS)
25{
26 text *t = PG_GETARG_TEXT_PP(0);
27 const char *qstr;
28 char *str;
29
30 str = text_to_cstring(t);
31 qstr = quote_identifier(str);
32 PG_RETURN_TEXT_P(cstring_to_text(qstr));
33}
34
35/*
36 * quote_literal_internal -
37 * helper function for quote_literal and quote_literal_cstr
38 *
39 * NOTE: think not to make this function's behavior change with
40 * standard_conforming_strings. We don't know where the result
41 * literal will be used, and so we must generate a result that
42 * will work with either setting. Take a look at what dblink
43 * uses this for before thinking you know better.
44 */
45static size_t
46quote_literal_internal(char *dst, const char *src, size_t len)
47{
48 const 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 */
76Datum
77quote_literal(PG_FUNCTION_ARGS)
78{
79 text *t = PG_GETARG_TEXT_PP(0);
80 text *result;
81 char *cp1;
82 char *cp2;
83 int len;
84
85 len = VARSIZE_ANY_EXHDR(t);
86 /* We make a worst-case result area; wasting a little space is OK */
87 result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
88
89 cp1 = VARDATA_ANY(t);
90 cp2 = VARDATA(result);
91
92 SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
93
94 PG_RETURN_TEXT_P(result);
95}
96
97/*
98 * quote_literal_cstr -
99 * returns a properly quoted literal
100 */
101char *
102quote_literal_cstr(const char *rawstr)
103{
104 char *result;
105 int len;
106 int newlen;
107
108 len = strlen(rawstr);
109 /* We make a worst-case result area; wasting a little space is OK */
110 result = palloc(len * 2 + 3 + 1);
111
112 newlen = quote_literal_internal(result, rawstr, len);
113 result[newlen] = '\0';
114
115 return result;
116}
117
118/*
119 * quote_nullable -
120 * Returns a properly quoted literal, with null values returned
121 * as the text string 'NULL'.
122 */
123Datum
124quote_nullable(PG_FUNCTION_ARGS)
125{
126 if (PG_ARGISNULL(0))
127 PG_RETURN_TEXT_P(cstring_to_text("NULL"));
128 else
129 PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
130 PG_GETARG_DATUM(0)));
131}
132