TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * quote.c
4 : * Functions for quoting identifiers and literals
5 : *
6 : * Portions Copyright (c) 2000-2023, 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 : #include "varatt.h"
18 :
19 :
20 : /*
21 : * quote_ident -
22 : * returns a properly quoted identifier
23 : */
24 : Datum
25 GIC 3742 : quote_ident(PG_FUNCTION_ARGS)
26 ECB : {
27 GIC 3742 : text *t = PG_GETARG_TEXT_PP(0);
28 ECB : const char *qstr;
29 : char *str;
30 :
31 GIC 3742 : str = text_to_cstring(t);
32 CBC 3742 : qstr = quote_identifier(str);
33 3742 : PG_RETURN_TEXT_P(cstring_to_text(qstr));
34 ECB : }
35 :
36 : /*
37 : * quote_literal_internal -
38 : * helper function for quote_literal and quote_literal_cstr
39 : *
40 : * NOTE: think not to make this function's behavior change with
41 : * standard_conforming_strings. We don't know where the result
42 : * literal will be used, and so we must generate a result that
43 : * will work with either setting. Take a look at what dblink
44 : * uses this for before thinking you know better.
45 : */
46 : static size_t
47 GIC 4474 : quote_literal_internal(char *dst, const char *src, size_t len)
48 ECB : {
49 : const char *s;
50 GIC 4474 : char *savedst = dst;
51 ECB :
52 GIC 340717 : for (s = src; s < src + len; s++)
53 ECB : {
54 GIC 336248 : if (*s == '\\')
55 ECB : {
56 GIC 5 : *dst++ = ESCAPE_STRING_SYNTAX;
57 CBC 5 : break;
58 ECB : }
59 : }
60 :
61 GIC 4474 : *dst++ = '\'';
62 CBC 340724 : while (len-- > 0)
63 ECB : {
64 GIC 336250 : if (SQL_STR_DOUBLE(*src, true))
65 CBC 22 : *dst++ = *src;
66 336250 : *dst++ = *src++;
67 ECB : }
68 GIC 4474 : *dst++ = '\'';
69 ECB :
70 GIC 4474 : return dst - savedst;
71 ECB : }
72 :
73 : /*
74 : * quote_literal -
75 : * returns a properly quoted literal
76 : */
77 : Datum
78 GIC 1772 : quote_literal(PG_FUNCTION_ARGS)
79 ECB : {
80 GIC 1772 : text *t = PG_GETARG_TEXT_PP(0);
81 ECB : text *result;
82 : char *cp1;
83 : char *cp2;
84 : int len;
85 :
86 GIC 1772 : len = VARSIZE_ANY_EXHDR(t);
87 ECB : /* We make a worst-case result area; wasting a little space is OK */
88 GIC 1772 : result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
89 ECB :
90 GIC 1772 : cp1 = VARDATA_ANY(t);
91 CBC 1772 : cp2 = VARDATA(result);
92 ECB :
93 GIC 1772 : SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
94 ECB :
95 GIC 1772 : PG_RETURN_TEXT_P(result);
96 ECB : }
97 :
98 : /*
99 : * quote_literal_cstr -
100 : * returns a properly quoted literal
101 : */
102 : char *
103 GIC 2702 : quote_literal_cstr(const char *rawstr)
104 ECB : {
105 : char *result;
106 : int len;
107 : int newlen;
108 :
109 GIC 2702 : len = strlen(rawstr);
110 ECB : /* We make a worst-case result area; wasting a little space is OK */
111 GIC 2702 : result = palloc(len * 2 + 3 + 1);
112 ECB :
113 GIC 2702 : newlen = quote_literal_internal(result, rawstr, len);
114 CBC 2702 : result[newlen] = '\0';
115 ECB :
116 GIC 2702 : return result;
117 ECB : }
118 :
119 : /*
120 : * quote_nullable -
121 : * Returns a properly quoted literal, with null values returned
122 : * as the text string 'NULL'.
123 : */
124 : Datum
125 GIC 790 : quote_nullable(PG_FUNCTION_ARGS)
126 ECB : {
127 GIC 790 : if (PG_ARGISNULL(0))
128 CBC 42 : PG_RETURN_TEXT_P(cstring_to_text("NULL"));
129 ECB : else
130 GIC 748 : PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
131 ECB : PG_GETARG_DATUM(0)));
132 : }
|