]> granicus.if.org Git - postgresql/commitdiff
Use dollar-quoting for function bodies, unless disabled with
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Mar 2004 22:06:08 +0000 (22:06 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Mar 2004 22:06:08 +0000 (22:06 +0000)
--disable-dollar-quoting.

Andrew Dunstan

doc/src/sgml/ref/pg_dump.sgml
src/bin/pg_dump/dumputils.c
src/bin/pg_dump/dumputils.h
src/bin/pg_dump/pg_dump.c

index c6041237240204fe560e20c91e8eb6481ab3942d..d9c6b05abbca5665d2ee0cfd24b234047ce7d151 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.68 2003/12/01 22:07:58 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.69 2004/03/23 22:06:08 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -420,17 +420,15 @@ PostgreSQL documentation
      </varlistentry>
 
      <varlistentry>
-      <term><option>-X use-set-session-authorization</></term>
-      <term><option>--use-set-session-authorization</></term>
+      <term><option>-X disable-dollar-quoting</></term>
+      <term><option>--disable-dollar-quoting</></term>
       <listitem>
        <para>
-        This option is obsolete but still accepted for backwards
-       compatibility.
-        <application>pg_dump</application> now always behaves in the
-       way formerly selected by this option.
+        This option disables the use of dollar quoting for function bodies,
+        and forces them to be quoted using SQL standard string syntax.
        </para>
-      </listitem>
-     </varlistentry>
+     </listitem>
+    </varlistentry>
 
      <varlistentry>
       <term><option>-X disable-triggers</></term>
@@ -438,18 +436,18 @@ PostgreSQL documentation
       <listitem>
        <para>
         This option is only relevant when creating a data-only dump.
-       It instructs <application>pg_dump</application> to include commands
-       to temporarily disable triggers on the target tables while
-       the data is reloaded.  Use this if you have referential
-       integrity checks or other triggers on the tables that you
-       do not want to invoke during data reload.
+        It instructs <application>pg_dump</application> to include commands
+        to temporarily disable triggers on the target tables while
+        the data is reloaded.  Use this if you have referential
+        integrity checks or other triggers on the tables that you
+        do not want to invoke during data reload.
        </para>
 
        <para>
         Presently, the commands emitted for <option>--disable-triggers</>
-       must be done as superuser.  So, you should also specify
-       a superuser name with <option>-S</>, or preferably be careful to
-       start the resulting script as a superuser.
+        must be done as superuser.  So, you should also specify
+        a superuser name with <option>-S</>, or preferably be careful to
+        start the resulting script as a superuser.
        </para>
 
        <para>
@@ -460,14 +458,27 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-X use-set-session-authorization</></term>
+      <term><option>--use-set-session-authorization</></term>
+      <listitem>
+       <para>
+        This option is obsolete but still accepted for backwards
+        compatibility.
+        <application>pg_dump</application> now always behaves in the
+        way formerly selected by this option.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-Z <replaceable class="parameter">0..9</replaceable></option></term>
       <term><option>--compress=<replaceable class="parameter">0..9</replaceable></option></term>
       <listitem>
        <para>
-       Specify the compression level to use in archive formats that
-       support compression.  (Currently only the custom archive
-       format supports compression.)
+        Specify the compression level to use in archive formats that
+        support compression.  (Currently only the custom archive
+        format supports compression.)
        </para>
       </listitem>
      </varlistentry>
index 16f0bd8877d55143a40dd49b665556c0da15be2b..1dfe7801ec5585d475127f973564d59561596343 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.11 2004/01/07 00:44:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.12 2004/03/23 22:06:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -142,6 +142,65 @@ appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
 }
 
 
+/*
+ * Convert a string value to a dollar quoted literal and append it to
+ * the given buffer. If the dqprefix parameter is not NULL then the 
+ * dollar quote delimiter will begin with that (after the opening $).
+ *
+ * No escaping is done at all on str, in compliance with the rules
+ * for parsing dollar quoted strings.
+ */
+void
+appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
+{
+       static const char suffixes[] = "_XXXXXXX";
+       int nextchar = 0;
+       PQExpBuffer delimBuf = createPQExpBuffer();
+
+       /* start with $ + dqprefix if not NULL */
+       appendPQExpBufferChar(delimBuf, '$');
+       if (dqprefix)
+               appendPQExpBuffer(delimBuf, dqprefix);
+
+       /* 
+        * Make sure we choose a delimiter which (without the trailing $)
+        * is not present in the string being quoted. We don't check with the
+        * trailing $ because a string ending in $foo must not be quoted with
+        * $foo$.
+        */
+       while (strstr(str, delimBuf->data) != NULL)
+       {
+               appendPQExpBufferChar(delimBuf, suffixes[nextchar++]);
+               nextchar %= sizeof(suffixes)-1;
+       }
+
+       /* add trailing $ */
+       appendPQExpBufferChar(delimBuf, '$');
+
+       /* quote it and we are all done */
+       appendPQExpBufferStr(buf, delimBuf->data);
+       appendPQExpBufferStr(buf, str);
+       appendPQExpBufferStr(buf, delimBuf->data);
+
+       destroyPQExpBuffer(delimBuf);
+}
+
+
+/*
+ * Use dollar quoting if the string to be quoted contains ' or \,
+ * otherwise use standard quoting.
+ */
+void
+appendStringLiteralDQOpt(PQExpBuffer buf, const char *str, 
+                                                bool escapeAll, const char *dqprefix)
+{
+       if (strchr(str, '\'') == NULL && strchr(str, '\\') == NULL)
+               appendStringLiteral(buf,str,escapeAll);
+       else
+               appendStringLiteralDQ(buf,str,dqprefix);
+}
+
+
 /*
  * Convert backend's version string into a number.
  */
index c4a71f1c43be39cf94495a1b3d4510ef064fec45..577e07b00f969cd5ea0ce9efd6f1abdc77de2a02 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.10 2004/01/07 00:44:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.11 2004/03/23 22:06:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 extern const char *fmtId(const char *identifier);
 extern void appendStringLiteral(PQExpBuffer buf, const char *str,
                                        bool escapeAll);
+extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str, 
+                               const char *dqprefix);
+extern void appendStringLiteralDQOpt(PQExpBuffer buf, const char *str, 
+                               bool escapeAll, const char *dqprefix);
 extern int     parse_version(const char *versionString);
 extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems);
 extern bool buildACLCommands(const char *name, const char *type,
index 2449a881bcd0e761760479db3882ca138f5ae023..1721ea3ddd447cd550f0fda00452d131294a4c71 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.368 2004/03/20 20:09:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.369 2004/03/23 22:06:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -107,6 +107,9 @@ static const CatalogId nilCatalogId = { 0, 0 };
 static NamespaceInfo *g_namespaces;
 static int     g_numNamespaces;
 
+/* flag to turn on/off dollar quoting */
+static int     disable_dollar_quoting = 0;
+
 
 static void help(const char *progname);
 static NamespaceInfo *findNamespace(Oid nsoid, Oid objoid);
@@ -231,8 +234,9 @@ main(int argc, char **argv)
                 * the following options don't have an equivalent short option
                 * letter, but are available as '-X long-name'
                 */
-               {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+               {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
+               {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
 
                {NULL, 0, NULL, 0}
        };
@@ -385,10 +389,12 @@ main(int argc, char **argv)
                                 * require arguments should use '-X feature=foo'.
                                 */
                        case 'X':
-                               if (strcmp(optarg, "use-set-session-authorization") == 0)
-                                       /* no-op, still allowed for compatibility */ ;
+                               if (strcmp(optarg, "disable-dollar-quoting") == 0)
+                                       disable_dollar_quoting = 1;
                                else if (strcmp(optarg, "disable-triggers") == 0)
                                        disable_triggers = 1;
+                               else if (strcmp(optarg, "use-set-session-authorization") == 0)
+                                       /* no-op, still allowed for compatibility */ ;
                                else
                                {
                                        fprintf(stderr,
@@ -679,6 +685,8 @@ help(const char *progname)
                         "                           plain text format\n"));
        printf(_("  -t, --table=TABLE        dump the named table only\n"));
        printf(_("  -x, --no-privileges      do not dump privileges (grant/revoke)\n"));
+       printf(_("  -X disable-dollar-quoting, --disable-dollar-quoting\n"
+                        "                           disable dollar quoting, use SQL standard quoting\n"));
        printf(_("  -X disable-triggers, --disable-triggers\n"
                         "                           disable triggers during data-only restore\n"));
 
@@ -5076,7 +5084,14 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                if (strcmp(prosrc, "-") != 0)
                {
                        appendPQExpBuffer(asPart, ", ");
-                       appendStringLiteral(asPart, prosrc, false);
+                       /* 
+                        * where we have bin, use dollar quoting if allowed and src
+                        * contains quote or backslash; else use regular quoting.
+                        */
+                       if (disable_dollar_quoting)
+                               appendStringLiteral(asPart, prosrc, false);
+                       else
+                               appendStringLiteralDQOpt(asPart, prosrc, false, NULL);
                }
        }
        else
@@ -5084,7 +5099,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                if (strcmp(prosrc, "-") != 0)
                {
                        appendPQExpBuffer(asPart, "AS ");
-                       appendStringLiteral(asPart, prosrc, false);
+                       /* with no bin, dollar quote src unconditionally if allowed */
+                       if (disable_dollar_quoting)
+                               appendStringLiteral(asPart, prosrc, false);
+                       else
+                               appendStringLiteralDQ(asPart, prosrc, NULL);
                }
        }