Index: doc/src/sgml/ref/pg_dump.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/pg_dump.sgml,v retrieving revision 1.68 diff -c -r1.68 pg_dump.sgml *** doc/src/sgml/ref/pg_dump.sgml 1 Dec 2003 22:07:58 -0000 1.68 --- doc/src/sgml/ref/pg_dump.sgml 23 Mar 2004 19:30:59 -0000 *************** *** 461,466 **** --- 461,477 ---- + + + + + This option disables the use of dollar quoting for function bodies, + and forces them to be quoted using SQL standard strings. + + + + + Index: src/bin/pg_dump/dumputils.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/pg_dump/dumputils.c,v retrieving revision 1.11 diff -c -r1.11 dumputils.c *** src/bin/pg_dump/dumputils.c 7 Jan 2004 00:44:21 -0000 1.11 --- src/bin/pg_dump/dumputils.c 23 Mar 2004 19:30:59 -0000 *************** *** 143,148 **** --- 143,205 ---- /* + * 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 char suffixes[] = "_XXXXXXXX"; + int nextchar = 0; + PQExpBuffer delimBuf = createPQExpBuffer(); + + /* start with $ + dqprefix if not NULL */ + appendPQExpBufferChar(delimBuf, '$'); + if (dqprefix) + appendPQExpBuffer(delimBuf, dqprefix); + + /* + * make sure we have a delimiter which (without the trailing $) + * is not preent in the string being quoted. We don't check with the + * trailing $ so that a string ending in $foo is not 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 */ + appendPQExpBuffer(buf,"%s%s%s",delimBuf->data,str,delimBuf->data); + destroyPQExpBuffer(delimBuf); + + } + + /* + * use dollar quoting if the string to be quoted contains ' or \, + * otherwise use standard quoting. + */ + + + void appendStringLiteralDQFallback(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 Index: src/bin/pg_dump/dumputils.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/pg_dump/dumputils.h,v retrieving revision 1.10 diff -c -r1.10 dumputils.h *** src/bin/pg_dump/dumputils.h 7 Jan 2004 00:44:21 -0000 1.10 --- src/bin/pg_dump/dumputils.h 23 Mar 2004 19:30:59 -0000 *************** *** 21,26 **** --- 21,30 ---- 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 appendStringLiteralDQFallback(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: src/bin/pg_dump/pg_dump.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/pg_dump/pg_dump.c,v retrieving revision 1.368 diff -c -r1.368 pg_dump.c *** src/bin/pg_dump/pg_dump.c 20 Mar 2004 20:09:45 -0000 1.368 --- src/bin/pg_dump/pg_dump.c 23 Mar 2004 19:31:02 -0000 *************** *** 107,112 **** --- 107,115 ---- 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); *************** *** 233,238 **** --- 236,242 ---- */ {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, + {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {NULL, 0, NULL, 0} }; *************** *** 389,394 **** --- 393,400 ---- /* no-op, still allowed for compatibility */ ; else if (strcmp(optarg, "disable-triggers") == 0) disable_triggers = 1; + else if (strcmp(optarg,"disable-dollar-quoting") == 0) + disable_dollar_quoting = true; else { fprintf(stderr, *************** *** 681,686 **** --- 687,694 ---- printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n")); + printf(_(" -X disable-dollar-quoting, --disable-dollar-quoting\n" + " disable dollar quoting, use SQL standard quoting\n")); printf(_("\nConnection options:\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); *************** *** 5076,5082 **** if (strcmp(prosrc, "-") != 0) { appendPQExpBuffer(asPart, ", "); ! appendStringLiteral(asPart, prosrc, false); } } else --- 5084,5097 ---- if (strcmp(prosrc, "-") != 0) { appendPQExpBuffer(asPart, ", "); ! /* ! * where we have bin, use dollar quoting if allowed ! * conditionally on src ! */ ! if (disable_dollar_quoting) ! appendStringLiteral(asPart, prosrc, false); ! else ! appendStringLiteralDQFallback(asPart, prosrc, false, NULL); } } else *************** *** 5084,5090 **** if (strcmp(prosrc, "-") != 0) { appendPQExpBuffer(asPart, "AS "); ! appendStringLiteral(asPart, prosrc, false); } } --- 5099,5109 ---- if (strcmp(prosrc, "-") != 0) { appendPQExpBuffer(asPart, "AS "); ! /* with no bin, dollar quote src unconditionally if allowed */ ! if (disable_dollar_quoting) ! appendStringLiteral(asPart, prosrc, false); ! else ! appendStringLiteralDQ(asPart, prosrc, NULL); } }