]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/adt/quote.c
Add support for EUI-64 MAC addresses as macaddr8
[postgresql] / src / backend / utils / adt / quote.c
index 31991ee51edc73c7607139e2004b2168adb343d2..43e5bb79621e28c3c1829b79adf25dfb5be751af 100644 (file)
@@ -3,18 +3,17 @@
  * quote.c
  *       Functions for quoting identifiers and literals
  *
- * Portions Copyright (c) 2000-2006, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2000-2017, PostgreSQL Global Development Group
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.19 2006/05/26 23:48:54 momjian Exp $
+ *       src/backend/utils/adt/quote.c
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
 #include "utils/builtins.h"
-#include "parser/gramparse.h"
 
 
 /*
 Datum
 quote_ident(PG_FUNCTION_ARGS)
 {
-       text       *t = PG_GETARG_TEXT_P(0);
-       text       *result;
+       text       *t = PG_GETARG_TEXT_PP(0);
        const char *qstr;
        char       *str;
-       int                     len;
-
-       /* We have to convert to a C string to use quote_identifier */
-       len = VARSIZE(t) - VARHDRSZ;
-       str = (char *) palloc(len + 1);
-       memcpy(str, VARDATA(t), len);
-       str[len] = '\0';
 
+       str = text_to_cstring(t);
        qstr = quote_identifier(str);
+       PG_RETURN_TEXT_P(cstring_to_text(qstr));
+}
 
-       len = strlen(qstr);
-       result = (text *) palloc(len + VARHDRSZ);
-       VARATT_SIZEP(result) = len + VARHDRSZ;
-       memcpy(VARDATA(result), qstr, len);
+/*
+ * quote_literal_internal -
+ *       helper function for quote_literal and quote_literal_cstr
+ *
+ * NOTE: think not to make this function's behavior change with
+ * standard_conforming_strings.  We don't know where the result
+ * literal will be used, and so we must generate a result that
+ * will work with either setting.  Take a look at what dblink
+ * uses this for before thinking you know better.
+ */
+static size_t
+quote_literal_internal(char *dst, const char *src, size_t len)
+{
+       const char *s;
+       char       *savedst = dst;
 
-       PG_RETURN_TEXT_P(result);
+       for (s = src; s < src + len; s++)
+       {
+               if (*s == '\\')
+               {
+                       *dst++ = ESCAPE_STRING_SYNTAX;
+                       break;
+               }
+       }
+
+       *dst++ = '\'';
+       while (len-- > 0)
+       {
+               if (SQL_STR_DOUBLE(*src, true))
+                       *dst++ = *src;
+               *dst++ = *src++;
+       }
+       *dst++ = '\'';
+
+       return dst - savedst;
 }
 
 /*
@@ -53,39 +76,56 @@ quote_ident(PG_FUNCTION_ARGS)
 Datum
 quote_literal(PG_FUNCTION_ARGS)
 {
-       text       *t = PG_GETARG_TEXT_P(0);
+       text       *t = PG_GETARG_TEXT_PP(0);
        text       *result;
        char       *cp1;
        char       *cp2;
        int                     len;
 
-       len = VARSIZE(t) - VARHDRSZ;
+       len = VARSIZE_ANY_EXHDR(t);
        /* We make a worst-case result area; wasting a little space is OK */
        result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
 
-       cp1 = VARDATA(t);
+       cp1 = VARDATA_ANY(t);
        cp2 = VARDATA(result);
 
-       if (!standard_conforming_strings)
-               for (; len-- > 0; cp1++)
-                       if (*cp1 == '\\')
-                       {
-                               *cp2++ = ESCAPE_STRING_SYNTAX;
-                               break;
-                       }
-
-       len = VARSIZE(t) - VARHDRSZ;
-       cp1 = VARDATA(t);
-       *cp2++ = '\'';
-       while (len-- > 0)
-       {
-               if (SQL_STR_DOUBLE(*cp1, !standard_conforming_strings))
-                       *cp2++ = *cp1;
-               *cp2++ = *cp1++;
-       }
-       *cp2++ = '\'';
-
-       VARATT_SIZEP(result) = cp2 - ((char *) result);
+       SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
 
        PG_RETURN_TEXT_P(result);
 }
+
+/*
+ * quote_literal_cstr -
+ *       returns a properly quoted literal
+ */
+char *
+quote_literal_cstr(const char *rawstr)
+{
+       char       *result;
+       int                     len;
+       int                     newlen;
+
+       len = strlen(rawstr);
+       /* We make a worst-case result area; wasting a little space is OK */
+       result = palloc(len * 2 + 3 + 1);
+
+       newlen = quote_literal_internal(result, rawstr, len);
+       result[newlen] = '\0';
+
+       return result;
+}
+
+/*
+ * quote_nullable -
+ *       Returns a properly quoted literal, with null values returned
+ *       as the text string 'NULL'.
+ */
+Datum
+quote_nullable(PG_FUNCTION_ARGS)
+{
+       if (PG_ARGISNULL(0))
+               PG_RETURN_TEXT_P(cstring_to_text("NULL"));
+       else
+               PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
+                                                                                       PG_GETARG_DATUM(0)));
+}