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