summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-03-23 22:06:08 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-03-23 22:06:08 +0000
commitf862c42009cd3e2e5f1ea78496148dfecab6d6a7 (patch)
tree4769e37ddd77623ab235486c9297fa8a9268d7f3
parent48b2802eeeaa3d0aca615726728c115c00073d5d (diff)
downloadpostgresql-f862c42009cd3e2e5f1ea78496148dfecab6d6a7.tar.gz
Use dollar-quoting for function bodies, unless disabled with
--disable-dollar-quoting. Andrew Dunstan
-rw-r--r--doc/src/sgml/ref/pg_dump.sgml51
-rw-r--r--src/bin/pg_dump/dumputils.c61
-rw-r--r--src/bin/pg_dump/dumputils.h6
-rw-r--r--src/bin/pg_dump/pg_dump.c31
4 files changed, 121 insertions, 28 deletions
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index c604123724..d9c6b05abb 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -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>
@@ -461,13 +459,26 @@ PostgreSQL documentation
</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>
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 16f0bd8877..1dfe7801ec 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -143,6 +143,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.
*/
int
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index c4a71f1c43..577e07b00f 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,10 @@
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,
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2449a881bc..1721ea3ddd 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -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);
}
}