Header And Logo

PostgreSQL
| The world's most advanced open source database.

quote.c

Go to the documentation of this file.
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 }