00001 /*------------------------------------------------------------------------- 00002 * 00003 * quote.c 00004 * Functions for quoting identifiers and literals 00005 * 00006 * Portions Copyright (c) 2000-2013, PostgreSQL Global Development Group 00007 * 00008 * 00009 * IDENTIFICATION 00010 * src/backend/utils/adt/quote.c 00011 * 00012 *------------------------------------------------------------------------- 00013 */ 00014 #include "postgres.h" 00015 00016 #include "utils/builtins.h" 00017 00018 00019 /* 00020 * quote_ident - 00021 * returns a properly quoted identifier 00022 */ 00023 Datum 00024 quote_ident(PG_FUNCTION_ARGS) 00025 { 00026 text *t = PG_GETARG_TEXT_PP(0); 00027 const char *qstr; 00028 char *str; 00029 00030 str = text_to_cstring(t); 00031 qstr = quote_identifier(str); 00032 PG_RETURN_TEXT_P(cstring_to_text(qstr)); 00033 } 00034 00035 /* 00036 * quote_literal_internal - 00037 * helper function for quote_literal and quote_literal_cstr 00038 * 00039 * NOTE: think not to make this function's behavior change with 00040 * standard_conforming_strings. We don't know where the result 00041 * literal will be used, and so we must generate a result that 00042 * will work with either setting. Take a look at what dblink 00043 * uses this for before thinking you know better. 00044 */ 00045 static size_t 00046 quote_literal_internal(char *dst, const char *src, size_t len) 00047 { 00048 const char *s; 00049 char *savedst = dst; 00050 00051 for (s = src; s < src + len; s++) 00052 { 00053 if (*s == '\\') 00054 { 00055 *dst++ = ESCAPE_STRING_SYNTAX; 00056 break; 00057 } 00058 } 00059 00060 *dst++ = '\''; 00061 while (len-- > 0) 00062 { 00063 if (SQL_STR_DOUBLE(*src, true)) 00064 *dst++ = *src; 00065 *dst++ = *src++; 00066 } 00067 *dst++ = '\''; 00068 00069 return dst - savedst; 00070 } 00071 00072 /* 00073 * quote_literal - 00074 * returns a properly quoted literal 00075 */ 00076 Datum 00077 quote_literal(PG_FUNCTION_ARGS) 00078 { 00079 text *t = PG_GETARG_TEXT_P(0); 00080 text *result; 00081 char *cp1; 00082 char *cp2; 00083 int len; 00084 00085 len = VARSIZE(t) - VARHDRSZ; 00086 /* We make a worst-case result area; wasting a little space is OK */ 00087 result = (text *) palloc(len * 2 + 3 + VARHDRSZ); 00088 00089 cp1 = VARDATA(t); 00090 cp2 = VARDATA(result); 00091 00092 SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len)); 00093 00094 PG_RETURN_TEXT_P(result); 00095 } 00096 00097 /* 00098 * quote_literal_cstr - 00099 * returns a properly quoted literal 00100 */ 00101 char * 00102 quote_literal_cstr(const char *rawstr) 00103 { 00104 char *result; 00105 int len; 00106 int newlen; 00107 00108 len = strlen(rawstr); 00109 /* We make a worst-case result area; wasting a little space is OK */ 00110 result = palloc(len * 2 + 3); 00111 00112 newlen = quote_literal_internal(result, rawstr, len); 00113 result[newlen] = '\0'; 00114 00115 return result; 00116 } 00117 00118 /* 00119 * quote_nullable - 00120 * Returns a properly quoted literal, with null values returned 00121 * as the text string 'NULL'. 00122 */ 00123 Datum 00124 quote_nullable(PG_FUNCTION_ARGS) 00125 { 00126 if (PG_ARGISNULL(0)) 00127 PG_RETURN_TEXT_P(cstring_to_text("NULL")); 00128 else 00129 PG_RETURN_DATUM(DirectFunctionCall1(quote_literal, 00130 PG_GETARG_DATUM(0))); 00131 }