Coverage Report

Created: 2026-10-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/utils/adt/quote.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * quote.c
4
 *    Functions for quoting identifiers and literals
5
 *
6
 * Portions Copyright (c) 2000-2026, 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
quote_ident(PG_FUNCTION_ARGS)
26
0
{
27
0
  text     *t = PG_GETARG_TEXT_PP(0);
28
0
  const char *qstr;
29
0
  char     *str;
30
31
0
  str = text_to_cstring(t);
32
0
  qstr = quote_identifier(str);
33
0
  PG_RETURN_TEXT_P(cstring_to_text(qstr));
34
0
}
35
36
/*
37
 * quote_literal_internal -
38
 *    helper function for quote_literal and quote_literal_cstr
39
 *
40
 * NOTE: This must produce output that will work in old servers with
41
 * standard_conforming_strings = off.  It's used for example by
42
 * dblink, which may send the result to another server.
43
 */
44
static size_t
45
quote_literal_internal(char *dst, const char *src, size_t len)
46
0
{
47
0
  const char *s;
48
0
  char     *savedst = dst;
49
50
0
  for (s = src; s < src + len; s++)
51
0
  {
52
0
    if (*s == '\\')
53
0
    {
54
0
      *dst++ = ESCAPE_STRING_SYNTAX;
55
0
      break;
56
0
    }
57
0
  }
58
59
0
  *dst++ = '\'';
60
0
  while (len-- > 0)
61
0
  {
62
0
    if (SQL_STR_DOUBLE(*src, true))
63
0
      *dst++ = *src;
64
0
    *dst++ = *src++;
65
0
  }
66
0
  *dst++ = '\'';
67
68
0
  return dst - savedst;
69
0
}
70
71
/*
72
 * quote_literal -
73
 *    returns a properly quoted literal
74
 */
75
Datum
76
quote_literal(PG_FUNCTION_ARGS)
77
0
{
78
0
  text     *t = PG_GETARG_TEXT_PP(0);
79
0
  text     *result;
80
0
  char     *cp1;
81
0
  char     *cp2;
82
0
  int     len;
83
84
0
  len = VARSIZE_ANY_EXHDR(t);
85
  /* We make a worst-case result area; wasting a little space is OK */
86
0
  result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
87
88
0
  cp1 = VARDATA_ANY(t);
89
0
  cp2 = VARDATA(result);
90
91
0
  SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
92
93
0
  PG_RETURN_TEXT_P(result);
94
0
}
95
96
/*
97
 * quote_literal_cstr -
98
 *    returns a properly quoted literal
99
 */
100
char *
101
quote_literal_cstr(const char *rawstr)
102
0
{
103
0
  char     *result;
104
0
  int     len;
105
0
  int     newlen;
106
107
0
  len = strlen(rawstr);
108
  /* We make a worst-case result area; wasting a little space is OK */
109
0
  result = palloc(
110
0
          (len * 2) /* doubling for every character if each one is
111
                 * a quote */
112
0
          + 3     /* two outer quotes + possibly 'E' if needed */
113
0
          + 1     /* null terminator */
114
0
    );
115
116
0
  newlen = quote_literal_internal(result, rawstr, len);
117
0
  result[newlen] = '\0';
118
119
0
  return result;
120
0
}
121
122
/*
123
 * quote_nullable -
124
 *    Returns a properly quoted literal, with null values returned
125
 *    as the text string 'NULL'.
126
 */
127
Datum
128
quote_nullable(PG_FUNCTION_ARGS)
129
0
{
130
0
  if (PG_ARGISNULL(0))
131
0
    PG_RETURN_TEXT_P(cstring_to_text("NULL"));
132
0
  else
133
0
    PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
134
0
                      PG_GETARG_DATUM(0)));
135
0
}