LCOV - code coverage report
Current view: top level - src/backend/utils/adt - quote.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 37 37 100.0 %
Date: 2026-02-01 21:16:50 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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        8744 : quote_ident(PG_FUNCTION_ARGS)
      26             : {
      27        8744 :     text       *t = PG_GETARG_TEXT_PP(0);
      28             :     const char *qstr;
      29             :     char       *str;
      30             : 
      31        8744 :     str = text_to_cstring(t);
      32        8744 :     qstr = quote_identifier(str);
      33        8744 :     PG_RETURN_TEXT_P(cstring_to_text(qstr));
      34             : }
      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        9588 : quote_literal_internal(char *dst, const char *src, size_t len)
      46             : {
      47             :     const char *s;
      48        9588 :     char       *savedst = dst;
      49             : 
      50      700882 :     for (s = src; s < src + len; s++)
      51             :     {
      52      691304 :         if (*s == '\\')
      53             :         {
      54          10 :             *dst++ = ESCAPE_STRING_SYNTAX;
      55          10 :             break;
      56             :         }
      57             :     }
      58             : 
      59        9588 :     *dst++ = '\'';
      60      700896 :     while (len-- > 0)
      61             :     {
      62      691308 :         if (SQL_STR_DOUBLE(*src, true))
      63          48 :             *dst++ = *src;
      64      691308 :         *dst++ = *src++;
      65             :     }
      66        9588 :     *dst++ = '\'';
      67             : 
      68        9588 :     return dst - savedst;
      69             : }
      70             : 
      71             : /*
      72             :  * quote_literal -
      73             :  *    returns a properly quoted literal
      74             :  */
      75             : Datum
      76        3538 : quote_literal(PG_FUNCTION_ARGS)
      77             : {
      78        3538 :     text       *t = PG_GETARG_TEXT_PP(0);
      79             :     text       *result;
      80             :     char       *cp1;
      81             :     char       *cp2;
      82             :     int         len;
      83             : 
      84        3538 :     len = VARSIZE_ANY_EXHDR(t);
      85             :     /* We make a worst-case result area; wasting a little space is OK */
      86        3538 :     result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
      87             : 
      88        3538 :     cp1 = VARDATA_ANY(t);
      89        3538 :     cp2 = VARDATA(result);
      90             : 
      91        3538 :     SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
      92             : 
      93        3538 :     PG_RETURN_TEXT_P(result);
      94             : }
      95             : 
      96             : /*
      97             :  * quote_literal_cstr -
      98             :  *    returns a properly quoted literal
      99             :  */
     100             : char *
     101        6050 : quote_literal_cstr(const char *rawstr)
     102             : {
     103             :     char       *result;
     104             :     int         len;
     105             :     int         newlen;
     106             : 
     107        6050 :     len = strlen(rawstr);
     108             :     /* We make a worst-case result area; wasting a little space is OK */
     109        6050 :     result = palloc(
     110             :                     (len * 2)   /* doubling for every character if each one is
     111             :                                  * a quote */
     112             :                     + 3         /* two outer quotes + possibly 'E' if needed */
     113        6050 :                     + 1         /* null terminator */
     114             :         );
     115             : 
     116        6050 :     newlen = quote_literal_internal(result, rawstr, len);
     117        6050 :     result[newlen] = '\0';
     118             : 
     119        6050 :     return result;
     120             : }
     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        1580 : quote_nullable(PG_FUNCTION_ARGS)
     129             : {
     130        1580 :     if (PG_ARGISNULL(0))
     131          84 :         PG_RETURN_TEXT_P(cstring_to_text("NULL"));
     132             :     else
     133        1496 :         PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
     134             :                                             PG_GETARG_DATUM(0)));
     135             : }

Generated by: LCOV version 1.16