Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * quote.c
4 : * Functions for quoting identifiers and literals
5 : *
6 : * Portions Copyright (c) 2000-2017, 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 : */
23 : Datum
24 206 : quote_ident(PG_FUNCTION_ARGS)
25 : {
26 206 : text *t = PG_GETARG_TEXT_PP(0);
27 : const char *qstr;
28 : char *str;
29 :
30 206 : str = text_to_cstring(t);
31 206 : qstr = quote_identifier(str);
32 206 : 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 : */
45 : static size_t
46 698 : quote_literal_internal(char *dst, const char *src, size_t len)
47 : {
48 : const char *s;
49 698 : char *savedst = dst;
50 :
51 3720 : for (s = src; s < src + len; s++)
52 : {
53 3023 : if (*s == '\\')
54 : {
55 1 : *dst++ = ESCAPE_STRING_SYNTAX;
56 1 : break;
57 : }
58 : }
59 :
60 698 : *dst++ = '\'';
61 4419 : while (len-- > 0)
62 : {
63 3023 : if (SQL_STR_DOUBLE(*src, true))
64 2 : *dst++ = *src;
65 3023 : *dst++ = *src++;
66 : }
67 698 : *dst++ = '\'';
68 :
69 698 : return dst - savedst;
70 : }
71 :
72 : /*
73 : * quote_literal -
74 : * returns a properly quoted literal
75 : */
76 : Datum
77 445 : quote_literal(PG_FUNCTION_ARGS)
78 : {
79 445 : text *t = PG_GETARG_TEXT_PP(0);
80 : text *result;
81 : char *cp1;
82 : char *cp2;
83 : int len;
84 :
85 445 : len = VARSIZE_ANY_EXHDR(t);
86 : /* We make a worst-case result area; wasting a little space is OK */
87 445 : result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
88 :
89 445 : cp1 = VARDATA_ANY(t);
90 445 : cp2 = VARDATA(result);
91 :
92 445 : SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
93 :
94 445 : PG_RETURN_TEXT_P(result);
95 : }
96 :
97 : /*
98 : * quote_literal_cstr -
99 : * returns a properly quoted literal
100 : */
101 : char *
102 253 : quote_literal_cstr(const char *rawstr)
103 : {
104 : char *result;
105 : int len;
106 : int newlen;
107 :
108 253 : len = strlen(rawstr);
109 : /* We make a worst-case result area; wasting a little space is OK */
110 253 : result = palloc(len * 2 + 3 + 1);
111 :
112 253 : newlen = quote_literal_internal(result, rawstr, len);
113 253 : result[newlen] = '\0';
114 :
115 253 : 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 : */
123 : Datum
124 254 : quote_nullable(PG_FUNCTION_ARGS)
125 : {
126 254 : if (PG_ARGISNULL(0))
127 14 : PG_RETURN_TEXT_P(cstring_to_text("NULL"));
128 : else
129 240 : PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
130 : PG_GETARG_DATUM(0)));
131 : }
|