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