]> 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 cdbab8dcbb86690bc80ba070e4273e840d17e3d0..43e5bb79621e28c3c1829b79adf25dfb5be751af 100644 (file)
@@ -3,11 +3,11 @@
  * quote.c
  *       Functions for quoting identifiers and literals
  *
- * Portions Copyright (c) 2000-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 2000-2017, PostgreSQL Global Development Group
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.28 2010/01/02 16:57:55 momjian Exp $
+ *       src/backend/utils/adt/quote.c
  *
  *-------------------------------------------------------------------------
  */
@@ -33,8 +33,8 @@ quote_ident(PG_FUNCTION_ARGS)
 }
 
 /*
- * quote_literal -
- *       returns a properly quoted literal
+ * 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
@@ -42,46 +42,77 @@ quote_ident(PG_FUNCTION_ARGS)
  * 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;
+
+       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;
+}
+
+/*
+ * quote_literal -
+ *       returns a properly quoted literal
+ */
 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);
 
-       for (; len-- > 0; cp1++)
-       {
-               if (*cp1 == '\\')
-               {
-                       *cp2++ = ESCAPE_STRING_SYNTAX;
-                       break;
-               }
-       }
+       SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
 
-       len = VARSIZE(t) - VARHDRSZ;
-       cp1 = VARDATA(t);
+       PG_RETURN_TEXT_P(result);
+}
 
-       *cp2++ = '\'';
-       while (len-- > 0)
-       {
-               if (SQL_STR_DOUBLE(*cp1, true))
-                       *cp2++ = *cp1;
-               *cp2++ = *cp1++;
-       }
-       *cp2++ = '\'';
+/*
+ * 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);
 
-       SET_VARSIZE(result, cp2 - ((char *) result));
+       newlen = quote_literal_internal(result, rawstr, len);
+       result[newlen] = '\0';
 
-       PG_RETURN_TEXT_P(result);
+       return result;
 }
 
 /*